diff --git a/.eslintignore b/.eslintignore index fb459b34a21..e40c7f10392 100644 --- a/.eslintignore +++ b/.eslintignore @@ -8,9 +8,11 @@ lib/ace/mode/php/* lib/ace/mode/xml/* lib/ace/mode/xquery/* lib/ace/mode/xquery.js -lib/ace/test/asyncjs/ -lib/ace/lib/es5-shim.js -lib/ace/keyboard/vim*.js +lib/ace/mode/yaml/* +src/lib/default_english_messages.js +**/test/asyncjs/* +**/es5-shim.js +**/vim*.js experiments/ tool/ doc/ @@ -19,4 +21,6 @@ demo/ api/ **/* * **/node_modules -0* \ No newline at end of file +0* +esm-resolver.js +src/ext/diff/providers/* \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 89da3026afa..e2728a18a1d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,4 +1,10 @@ { + "parserOptions": { + "ecmaVersion": 2015 + }, + "env": { + "es6": true + }, "globals": { define: true, require: true, @@ -26,11 +32,13 @@ prompt: true, XMLHttpRequest: true, localStorage: true, + KeyboardEvent: true, + CustomEvent: true }, "rules": { curly: 0, eqeqeq: 0, - comma-dangle: 2, + //comma-dangle: 2, no-dupe-args: 2, no-dupe-keys: 2, no-duplicate-case: 2, @@ -48,7 +56,7 @@ no-unexpected-multiline: 2, use-isnan: 2, valid-typeof: 2, - + accessor-pairs: 2, complexity: 0, dot-location: [2, "property"], @@ -72,11 +80,11 @@ no-sequences: 2, no-useless-call: 2, yoda: 2, - + no-undef: 2, no-redeclare: 0, - // no-unused-vars: 1, - + no-unused-vars: [1, {"args": "none", "vars": "all"}], + no-debugger: 2, ////////////////////////////////////////////////////////////////// @@ -88,7 +96,7 @@ // no-useless-concat: 2, // no-eval: 2, // dot-notation: 2, - // no-alert: 2, + no-alert: 2, no-extra-semi: 2, // doesn't handle ;(function() {})() pattern // radix: 2, // no-invalid-this: 2, @@ -100,17 +108,17 @@ // no-else-return: 2, // no-unused-expressions: 2, // no-use-before-define: [2, { "functions": false, "classes": false, "variables": false }], - + // array-bracket-spacing: 2, // enforce spacing inside array brackets (fixable) // block-spacing: 2, // disallow or enforce spaces inside of single line blocks (fixable) - // brace-style: 2, // enforce one true brace style + // brace-style: 2, // enforce one true brace style // camelcase: 2, // require camel case names // comma-spacing: 2, // enforce spacing before and after comma (fixable) // comma-style: 2, // enforce one true comma style computed-property-spacing: 2, // require or disallow padding inside computed properties (fixable) - // consistent-this: 2, // enforce consistent naming when capturing the current execution context + // consistent-this: 2, // enforce consistent naming when capturing the current execution context linebreak-style: 2, // disallow mixed 'LF' and 'CRLF' as linebreaks - // indent: ["error", 4, { "outerIIFEBody": 0 }], // specify tab or space width for your code (fixable) + // indent: ["error", 4, { "outerIIFEBody": 0 }], // specify tab or space width for your code (fixable) // key-spacing: 2, // enforce spacing between keys and values in object literal properties // new-cap: 2, // require a capital letter for constructors // new-parens: 2, // disallow the omission of parentheses when invoking a constructor with no arguments @@ -143,6 +151,6 @@ // space-infix-ops: 2, // require spaces around operators (fixable) // space-unary-ops: 2, // require or disallow spaces before/after unary operators (fixable) // spaced-comment: [2, "always", { markers: ["-", "*", "/", "{", "}", "#"], exceptions: ["}"] }] - + } } diff --git a/.github/ISSUE_TEMPLATE/add-to-website.yml b/.github/ISSUE_TEMPLATE/add-to-website.yml new file mode 100644 index 00000000000..f8e865915bc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/add-to-website.yml @@ -0,0 +1,51 @@ +--- +name: "🌐 Add a project to the list of project using Ace on its website." +description: Add a project to the list of projects using Ace, displayed on the website. +title: "Add project (project name) to the list of projects using Ace on its website" +labels: [website, needs-triage] +assignees: [] +body: + - type: markdown + attributes: + value: | + The fastest way to get your project to be displayed on the website is to create a PR. + Examples: https://github.com/ajaxorg/ace/pull/5014, https://github.com/ajaxorg/ace/pull/5222. + If for any reason creating a PR is not an option for you, please proceed with filling out this issue. Thanks! + - type: input + id: name + attributes: + label: Project name + description: A name of the project to be used on Ace website. + validations: + required: true + - type: input + id: project-link + attributes: + label: Project link + description: A link to the project's website. + validations: + required: true + - type: input + id: logo-link + attributes: + label: Logo link + description: | + 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. + + By submitting this link, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. + validations: + required: false + - type: textarea + id: info + attributes: + label: Additional information + description: Any additional information you would like to share. + validations: + required: false + - type: checkboxes + id: ack + attributes: + label: Acknowledgements + options: + - label: I may be able to implement this request. + required: false diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 00000000000..3a3931524a4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,67 @@ +--- +name: "🐞 Bug Report" +description: Report a bug +title: "(module name): (short issue description)" +labels: [bug, needs-triage] +assignees: [] +body: + - type: textarea + id: description + attributes: + label: Describe the bug + description: What is the problem? A clear and concise description of the bug. + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected Behavior + description: | + What did you expect to happen? + validations: + required: true + - type: textarea + id: current + attributes: + label: Current Behavior + description: | + What actually happened? + + Please include full errors, uncaught exceptions, stack traces, and relevant logs. + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: Reproduction Steps + description: | + Provide a self-contained, concise snippet of code that can be used to reproduce the issue. + For more complex issues provide a repo with the smallest sample that reproduces the bug. + + Avoid including business logic or unrelated code, it makes diagnosis more difficult. + validations: + required: true + - type: textarea + id: solution + attributes: + label: Possible Solution + description: | + Suggest a fix/reason for the bug + validations: + required: false + - type: textarea + id: context + attributes: + label: Additional Information/Context + description: | + 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. + validations: + required: false + + - type: input + id: ace-version + attributes: + label: Ace Version / Browser / OS / Keyboard layout + description: Information about software versions and keyboard configuration that can be relevant for reproducing the issue + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..5b43894a794 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +--- +blank_issues_enabled: false +contact_links: + - name: 🤔 General Question + url: https://github.com/ajaxorg/ace/discussions/categories/q-a + about: Please ask and answer questions as a discussion thread diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml new file mode 100644 index 00000000000..29361a78480 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -0,0 +1,23 @@ +--- +name: "📕 Documentation Issue" +description: Report an issue in the documentation +title: "(short issue description)" +labels: [documentation, needs-triage] +assignees: [] +body: + - type: textarea + id: description + attributes: + label: Describe the issue + description: A clear and concise description of the issue. + validations: + required: true + + - type: textarea + id: links + attributes: + label: Links + description: | + Include links to affected documentation page(s). + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 00000000000..40778b549b3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,53 @@ +--- +name: 🚀 Feature Request +description: Suggest an idea for this project +title: "(short issue description)" +labels: [feature-request, needs-triage] +assignees: [] +body: + - type: textarea + id: description + attributes: + label: Describe the feature + description: A clear and concise description of the feature you are proposing. + validations: + required: true + - type: textarea + id: use-case + attributes: + label: Use Case + description: | + Why do you need this feature? For example: "I'm always frustrated when..." + validations: + required: true + - type: textarea + id: solution + attributes: + label: Proposed Solution + description: | + Suggest how to implement the addition or change. Please include prototype/workaround/sketch/reference implementation. + validations: + required: false + - type: textarea + id: other + attributes: + label: Other Information + description: | + Any alternative solutions or features you considered, a more detailed explanation, stack traces, related issues, links for context, etc. + validations: + required: false + - type: checkboxes + id: ack + attributes: + label: Acknowledgements + options: + - label: I may be able to implement this feature request + required: false + - label: This feature might incur a breaking change + required: false + - type: input + id: ace-version + attributes: + label: ACE version used + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000000..3cdc8e1949b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,13 @@ +*Issue #, if available:* + +*Description of changes:* + + +By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. + +Pull Request Checklist: +* [ ] 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: + * https://github.com/ajaxorg/ace/blob/master/ace.d.ts + * https://github.com/ajaxorg/ace/blob/master/ace-modes.d.ts + * https://github.com/ajaxorg/ace/blob/master/ace-extensions.d.ts + diff --git a/.github/workflows/backwards-compatibility-commenter.yml b/.github/workflows/backwards-compatibility-commenter.yml new file mode 100644 index 00000000000..c2d5a688df6 --- /dev/null +++ b/.github/workflows/backwards-compatibility-commenter.yml @@ -0,0 +1,20 @@ +name: Comments for ensuring backward compatibility + +on: + pull_request_target: + paths: + - 'ace.d.ts' + - 'ace-modes.d.ts' + - 'ace-extensions.d.ts' + +jobs: + comment: + runs-on: ubuntu-latest + steps: + - name: Comment on PR + uses: peter-evans/create-or-update-comment@v1 + with: + issue-number: ${{ github.event.pull_request.number }} + body: | + One of the public type files has been updated, plase make sure there are no backwards incompatible changes done in the PR. + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml new file mode 100644 index 00000000000..6ec9514b742 --- /dev/null +++ b/.github/workflows/close-stale-issues.yml @@ -0,0 +1,49 @@ +name: "Close Stale Issues" + +# Controls when the action will run. +on: + workflow_dispatch: + schedule: + - cron: "0 */4 * * *" + +jobs: + cleanup: + permissions: + issues: write + contents: read + pull-requests: write + runs-on: ubuntu-latest + name: Stale issue job + steps: + - uses: aws-actions/stale-issue-cleanup@v5 + with: + issue-types: issues + # Setting messages to an empty string will cause the automation to skip + # that category + 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. + 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. + + # These labels are required + stale-issue-label: closing-soon + exempt-issue-labels: no-autoclose, p1 + response-requested-label: response-requested + + # Don't set closed-for-staleness label to skip closing very old issues + # regardless of label + closed-for-staleness-label: closed-for-staleness + + # Issue timing + days-before-stale: 7 + days-before-close: 2 + days-before-ancient: 365 + + # If you don't want to mark a issue as being ancient based on a + # threshold of "upvotes", you can set this here. An "upvote" is + # the total number of +1, heart, hooray, and rocket reactions + # on an issue. + minimum-upvotes-to-exempt: 5 + + repo-token: ${{ secrets.GITHUB_TOKEN }} + loglevel: DEBUG + # Set dry-run to true to not perform label or close actions. + dry-run: false diff --git a/.github/workflows/issue-reprioritization.yml b/.github/workflows/issue-reprioritization.yml new file mode 100644 index 00000000000..06a8b3ee033 --- /dev/null +++ b/.github/workflows/issue-reprioritization.yml @@ -0,0 +1,22 @@ +name: issue-reprioritization +on: + schedule: + - cron: "0 0 * * 0" + +jobs: + issue-reprioritization: + permissions: + issues: write + runs-on: ubuntu-latest + steps: + - uses: kaizencc/issue-reprioritization-manager@main + id: reprioritization-manager + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + original-label: p2 + new-label: p1 + reprioritization-threshold: 5 + - uses: kaizencc/pr-triage-manager@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + on-pulls: ${{ steps.reprioritization-manager.outputs.linked-pulls }} diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml new file mode 100644 index 00000000000..50d9f943b0a --- /dev/null +++ b/.github/workflows/nodejs.yml @@ -0,0 +1,72 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + steps: + - uses: actions/checkout@v2 + - name: Fetch the master branch + run: git fetch origin HEAD:refs/remotes/origin/HEAD --depth 1 + - name: Fetch the master branch + run: git diff --name-only origin/HEAD --no-renames --diff-filter=ACMR + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm i + - run: npm run cover + # run linter + - run: | + set -x; + git status; + git checkout HEAD -- package.json; + changes=$(git diff --name-only origin/HEAD --no-renames --diff-filter=ACMR); + if [ "$changes" == "" ]; then + echo "checking all files"; + node node_modules/eslint/bin/eslint "lib/ace/**/*.js"; + else + jsChanges=$(echo "$changes" | grep -P '.js$' || :); + if [ "$jsChanges" == "" ]; then + echo "nothing to check"; + else + echo "checking $jsChanges"; + node node_modules/eslint/bin/eslint $jsChanges; + fi + fi + # check types + - run: | + set -x; + npx tsc -v; + npm run update-types; + git diff --color --exit-code ./ace*d.ts; + npm run typecheck; + node_modules/.bin/tsc --noImplicitAny --strict --noUnusedLocals --noImplicitReturns --noUnusedParameters --noImplicitThis ace.d.ts; + - run: | + set -x; + ./tool/test-npm-package.sh + # upload to codecov + - uses: codecov/codecov-action@v3 + with: + token: d8edca4b-8e97-41e5-b54e-34c7cf3b2d47 + file: ./coverage/coverage.json + flags: unittests + name: codecov-umbrella + fail_ci_if_error: true diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000000..b8f02b00108 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,26 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Publish to NPM +on: + push: + tags: + - v* + workflow_dispatch: +permissions: + contents: read # to fetch code (actions/checkout) +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + # Setup .npmrc file to publish to npm + - uses: actions/setup-node@v1 + with: + node-version: '16.x' + registry-url: 'https://registry.npmjs.org/' + - run: npm install + - run: npm run test + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_SECRET }} diff --git a/.gitignore b/.gitignore index 0e5c2abaab0..67ad0db2003 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # Project files that should not be in the repo .* \#* +!/.github !/.gitignore .*.gz *.tmTheme.js @@ -22,3 +23,7 @@ jam/ .git-ref npm-debug.log deps/ +dist + +lib/ace +styles \ No newline at end of file diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000000..52a439b526a --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ +disable jekyll on gh-pages diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6ab35e5e48a..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -language: node_js - -node_js: - - "4" - -install: - - cleanup() { find node_modules -regextype posix-extended -iregex '.*((test|example|doc|demo)s?|\.(md|ts)|license|idea|coverage|file.txt)$' -exec rm -rf {} \; || echo $?; }; - install() { npm i && npm i eslint codecov istanbul && cp package.json node_modules/package.json; cleanup; }; - cmp --silent package.json node_modules/package.json || install; - -script: - - node node_modules/eslint/bin/eslint "lib/ace/**/*.js" - - node_modules/.bin/istanbul cover lib/ace/test/all.js - - node_modules/.bin/codecov - -matrix: - fast_finish: false - -cache: - directories: - - node_modules - -sudo: false - -git: - depth: 1 - submodules: false - -branches: - only: - - master \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..7b0ad15be9d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,1505 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +### [1.43.4](https://github.com/ajaxorg/ace/compare/v1.43.3...v1.43.4) (2025-10-17) + + +### Bug Fixes + +* Update for compliance with typescript 5.9.2 ([#5855](https://github.com/ajaxorg/ace/issues/5855)) ([6e110b0](https://github.com/ajaxorg/ace/commit/6e110b0061b56b72db7478762036a1ba39251102)) + +### [1.43.3](https://github.com/ajaxorg/ace/compare/v1.43.2...v1.43.3) (2025-09-02) + + +### Bug Fixes + +* firefox textarea autocomplete corruption ([#5860](https://github.com/ajaxorg/ace/issues/5860)) ([23ac02f](https://github.com/ajaxorg/ace/commit/23ac02f7602b84cc4ea30f6ed4f889d3802affde)) + +### [1.43.2](https://github.com/ajaxorg/ace/compare/v1.43.1...v1.43.2) (2025-07-15) + + +### Features + +* Implement text markers ([#5835](https://github.com/ajaxorg/ace/issues/5835)) ([085730f](https://github.com/ajaxorg/ace/commit/085730fff987ec88c2350146f18b42b17532d47f)) + +### [1.43.1](https://github.com/ajaxorg/ace/compare/v1.43.0...v1.43.1) (2025-07-02) + + +### Bug Fixes + +* **a11y:** aria-describedby to gutter elements ([#5838](https://github.com/ajaxorg/ace/issues/5838)) ([bf27c15](https://github.com/ajaxorg/ace/commit/bf27c151685ac486a991a61d67fa04adf8891c76)) + +### [1.42.1](https://github.com/ajaxorg/ace/compare/v1.42.0...v1.42.1) (2025-06-20) + + +### Features + +* Add scroll diff decorators ([#5807](https://github.com/ajaxorg/ace/issues/5807)) ([b45e94c](https://github.com/ajaxorg/ace/commit/b45e94cb92d757b5f09ee0966a764ed0d245ed70)) + +## [1.42.0](https://github.com/ajaxorg/ace/compare/v1.41.0...v1.42.0) (2025-06-03) + + +### Features + +* 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) + + +### Bug Fixes + +* editor.completer would init on `enableBasicAutocompletion` option `true` ([#5756](https://github.com/ajaxorg/ace/issues/5756)) ([25a471a](https://github.com/ajaxorg/ace/commit/25a471a3ec0a7c657646a54d034709f0d3283f19)) +* missing type aliases and MarkerGroup in `ace-builds` ([#5782](https://github.com/ajaxorg/ace/issues/5782)) ([b20be1a](https://github.com/ajaxorg/ace/commit/b20be1a4591e1c566fdb0e205a75fa580885e7c6)) + +### [1.40.2](https://github.com/ajaxorg/ace/compare/v1.40.1...v1.40.2) (2025-05-02) + +### [1.40.1](https://github.com/ajaxorg/ace/compare/v1.40.0...v1.40.1) (2025-04-23) + + +### Bug Fixes + +* **gutter:** add null check for session.foldWdigets ([#5801](https://github.com/ajaxorg/ace/issues/5801)) ([6ca40e9](https://github.com/ajaxorg/ace/commit/6ca40e93623ed1d4d04c8ce7ffb45186092c2198)) + +## [1.40.0](https://github.com/ajaxorg/ace/compare/v1.39.1...v1.40.0) (2025-04-15) + + +### Features + +* **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)) + +### [1.39.1](https://github.com/ajaxorg/ace/compare/v1.39.0...v1.39.1) (2025-03-20) + + +### Features + +* Editing is disabled tooltip in readonly mode ([#5771](https://github.com/ajaxorg/ace/issues/5771)) ([1098e53](https://github.com/ajaxorg/ace/commit/1098e5306fdc02e873cdadc85d2e13228abfe80c)) + + +### Bug Fixes + +* Fix is check in xml FoldMode ([#5752](https://github.com/ajaxorg/ace/issues/5752)) ([810c465](https://github.com/ajaxorg/ace/commit/810c4650288d32b119239f7731a3b3be0c25376c)) +* replace NodeList.foreach with for loop ([#5769](https://github.com/ajaxorg/ace/issues/5769)) ([b3de3c1](https://github.com/ajaxorg/ace/commit/b3de3c1d99540bd94df122cedb7c5e3a792986a7)) +* updateDocTooltip with undefined this.completions ([#5754](https://github.com/ajaxorg/ace/issues/5754)) ([adde072](https://github.com/ajaxorg/ace/commit/adde072dd4810aa8f99bb1e16a6ab7dfc81a6e9d)) +* wrong java keywords ([#5759](https://github.com/ajaxorg/ace/issues/5759)) ([6b4c7a0](https://github.com/ajaxorg/ace/commit/6b4c7a09d844a2e16d664d3e9fbb384b543bcfcb)) + +## [1.39.0](https://github.com/ajaxorg/ace/compare/v1.38.0...v1.39.0) (2025-02-21) + + +### Features + +* Multiline Search Support: line breaks `\n` ([#5675](https://github.com/ajaxorg/ace/issues/5675)) ([06d51b9](https://github.com/ajaxorg/ace/commit/06d51b9164dc9dc39fbd6df26b7132f4b9580a4c)) + + +### Bug Fixes + +* 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)) +* gutter hover tooltip a11y improvements ([#5747](https://github.com/ajaxorg/ace/issues/5747)) ([fbe3ddc](https://github.com/ajaxorg/ace/commit/fbe3ddccb1248c9f8f4a6524d2ded7235d225b41)) +* narrowing platform to be either win or mac ([#5707](https://github.com/ajaxorg/ace/issues/5707)) ([18cc336](https://github.com/ajaxorg/ace/commit/18cc336187519107f47bb15e989008f48f0b1563)) +* set score completion item when skipfilter true ([#5749](https://github.com/ajaxorg/ace/issues/5749)) ([a27e1e8](https://github.com/ajaxorg/ace/commit/a27e1e8a5d3d912b3b554cd2b5916b58750e8e71)) + +## [1.38.0](https://github.com/ajaxorg/ace/compare/v1.37.5...v1.38.0) (2025-02-12) + + +### Features + +* **popup:** add supporting skipFilter flag for popup item ([#5740](https://github.com/ajaxorg/ace/issues/5740)) ([0db7585](https://github.com/ajaxorg/ace/commit/0db7585ae0ccbd353091426f60ac3d9e53e182c4)) + + +### Bug Fixes + +* **AcePopup:** fix aria-posinset issue on google chrome ([#5719](https://github.com/ajaxorg/ace/issues/5719)) ([09a0c5a](https://github.com/ajaxorg/ace/commit/09a0c5a11106754916a4fc324a35e8daf84055ba)) +* 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)) +* highlight indent guides with wrapped lines ([#5621](https://github.com/ajaxorg/ace/issues/5621)) ([77b9fe1](https://github.com/ajaxorg/ace/commit/77b9fe1bc0b10b4c3fb2780d65f9d256d60634ce)) +* improve aria attributes of popup elements ([#5739](https://github.com/ajaxorg/ace/issues/5739)) ([09fba2e](https://github.com/ajaxorg/ace/commit/09fba2e7347cd499c979e53ec7a8d8ee1fd48918)) +* types for setTimeout/setInterval calls ([#5726](https://github.com/ajaxorg/ace/issues/5726)) ([9a76656](https://github.com/ajaxorg/ace/commit/9a76656acc9528a4a2e92a3b72c4d6598d3a0a8c)) +* **VirtualRenderer:** fix scrollbar overlap on autocompletion ([#5713](https://github.com/ajaxorg/ace/issues/5713)) ([5acea6d](https://github.com/ajaxorg/ace/commit/5acea6d9200f4ca0c8495350cda6e41e8351913f)) +* 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)) + +### [1.37.5](https://github.com/ajaxorg/ace/compare/v1.37.4...v1.37.5) (2025-01-16) + + +### Bug Fixes + +* update aria-roledescription gutter ([#5718](https://github.com/ajaxorg/ace/issues/5718)) ([7ae3a4c](https://github.com/ajaxorg/ace/commit/7ae3a4c5f6f6e9bd31ae491f1fcef71fc5ae62fa)) + +### [1.37.4](https://github.com/ajaxorg/ace/compare/v1.37.3...v1.37.4) (2025-01-09) + + +### Bug Fixes + +* Remove unnecesary `typeof` from type imports in declarations ([#5715](https://github.com/ajaxorg/ace/issues/5715)) ([2c8bf91](https://github.com/ajaxorg/ace/commit/2c8bf916d75b086b958c205896bc2adc1747d241)) + +### [1.37.3](https://github.com/ajaxorg/ace/compare/v1.37.2...v1.37.3) (2025-01-07) + +### [1.37.2](https://github.com/ajaxorg/ace/compare/v1.37.1...v1.37.2) (2025-01-06) + + +### Bug Fixes + +* fix return type of supportsFile modelist ([#5705](https://github.com/ajaxorg/ace/issues/5705)) ([de21d50](https://github.com/ajaxorg/ace/commit/de21d50656bd874e1626265b8853923cb8da7c8b)) + +### [1.37.1](https://github.com/ajaxorg/ace/compare/v1.37.0...v1.37.1) (2024-12-20) + + +### Bug Fixes + +* hide gutter tooltip event missing from editor signal ([#5701](https://github.com/ajaxorg/ace/issues/5701)) ([66a6736](https://github.com/ajaxorg/ace/commit/66a673643d5d128eaf59d4fb6e5907fa6fa68773)) + +### [1.36.6](https://github.com/ajaxorg/ace/compare/v1.36.5...v1.36.6) (2024-12-17) + + +### Bug Fixes + +* update contribuition guide to mandate test cases ([#5694](https://github.com/ajaxorg/ace/issues/5694)) ([e6533b3](https://github.com/ajaxorg/ace/commit/e6533b3972d5adbf5995646c44894466b3b7f40f)) +* wrong behaviour rules in modes ([#5682](https://github.com/ajaxorg/ace/issues/5682)) ([442680c](https://github.com/ajaxorg/ace/commit/442680c68e66531c2d5ac80d80444ed600262ec1)) + +### [1.36.5](https://github.com/ajaxorg/ace/compare/v1.36.4...v1.36.5) (2024-11-14) + + +### Features + +* 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)) + + +### Bug Fixes + +* vue-directives regex bug ([#5671](https://github.com/ajaxorg/ace/issues/5671)) ([5e1e524](https://github.com/ajaxorg/ace/commit/5e1e524d7ef04e13291b5a979fb4166e973e61f0)) + +### [1.36.4](https://github.com/ajaxorg/ace/compare/v1.36.3...v1.36.4) (2024-11-04) + + +### Bug Fixes + +* **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)) + +### [1.36.3](https://github.com/ajaxorg/ace/compare/v1.36.2...v1.36.3) (2024-10-21) + + +### Bug Fixes + +* `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)) + +### [1.36.2](https://github.com/ajaxorg/ace/compare/v1.36.1...v1.36.2) (2024-08-30) + + +### Bug Fixes + +* apply padding to right side multi-line markers ([#5636](https://github.com/ajaxorg/ace/issues/5636)) ([c7549aa](https://github.com/ajaxorg/ace/commit/c7549aa5d53fb62f134b31a44d09029ceee3c800)) + +### [1.36.1](https://github.com/ajaxorg/ace/compare/v1.36.0...v1.36.1) (2024-08-29) + + +### Bug Fixes + +* improve type getMarkerAtPosition markergroup ([#5631](https://github.com/ajaxorg/ace/issues/5631)) ([89bd40a](https://github.com/ajaxorg/ace/commit/89bd40a66a2f06fb8806f174e5559021540a5b1e)) +* update cloudeditor light colours ([#5633](https://github.com/ajaxorg/ace/issues/5633)) ([0e2813e](https://github.com/ajaxorg/ace/commit/0e2813ed9e858d9359c2a79f2a9255d675308ad1)) + +## [1.36.0](https://github.com/ajaxorg/ace/compare/v1.35.5...v1.36.0) (2024-08-21) + + +### Features + +* allow setting marker type for MarkerGroups ([#5630](https://github.com/ajaxorg/ace/issues/5630)) ([214df9c](https://github.com/ajaxorg/ace/commit/214df9cea8d729f3071f9c02889cba2b2e7051b3)) +* **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)) + +### [1.35.5](https://github.com/ajaxorg/ace/compare/v1.35.4...v1.35.5) (2024-08-20) + +### [1.35.4](https://github.com/ajaxorg/ace/compare/v1.35.3...v1.35.4) (2024-07-22) + + +### Bug Fixes + +* 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)) + +### [1.35.3](https://github.com/ajaxorg/ace/compare/v1.35.2...v1.35.3) (2024-07-18) + + +### Bug Fixes + +* ghost text rendering of empty lines ([#5615](https://github.com/ajaxorg/ace/issues/5615)) ([1ae0bdc](https://github.com/ajaxorg/ace/commit/1ae0bdcfb9da4078713d116e93a9c9a935a1258d)) + +### [1.35.2](https://github.com/ajaxorg/ace/compare/v1.35.1...v1.35.2) (2024-07-01) + +### [1.35.1](https://github.com/ajaxorg/ace/compare/v1.35.0...v1.35.1) (2024-06-27) + + +### Bug Fixes + +* explicitly construct Number from window zoom attribute ([#5600](https://github.com/ajaxorg/ace/issues/5600)) ([2591c36](https://github.com/ajaxorg/ace/commit/2591c36b9e768305a9f837bf74c828c2d8d76e05)) +* 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)) +* workaround for safari rendering bug ([#5573](https://github.com/ajaxorg/ace/issues/5573)) ([f9a152f](https://github.com/ajaxorg/ace/commit/f9a152fd925a8a16b10c65c909201100486c71e8)) +* wrong doc comment * insert behaviour ([#5571](https://github.com/ajaxorg/ace/issues/5571)) ([16c95b3](https://github.com/ajaxorg/ace/commit/16c95b32197c0ec952e52be85d21269005875940)) + +## [1.35.0](https://github.com/ajaxorg/ace/compare/v1.34.2...v1.35.0) (2024-06-11) + + +### Features + +* allow '{n}' as placeholder for translated strings ([#5581](https://github.com/ajaxorg/ace/issues/5581)) ([2206024](https://github.com/ajaxorg/ace/commit/220602488b95748c74141d647e13114c7a4569fb)) + + +### Bug Fixes + +* allow setting the placeholder type for nls ([#5584](https://github.com/ajaxorg/ace/issues/5584)) ([3e2d50f](https://github.com/ajaxorg/ace/commit/3e2d50f5307e201c20825311585e1f612f1ff23c)) +* 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)) +* wrong vue-directives regexp ([#5586](https://github.com/ajaxorg/ace/issues/5586)) ([5f89a33](https://github.com/ajaxorg/ace/commit/5f89a334e69640bb395e74ae86530217d08f141c)) + +### [1.34.2](https://github.com/ajaxorg/ace/compare/v1.34.1...v1.34.2) (2024-05-27) + +### [1.34.1](https://github.com/ajaxorg/ace/compare/v1.34.0...v1.34.1) (2024-05-24) + + +### Bug Fixes + +* 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)) +* Folding for comments and different modes ([#5533](https://github.com/ajaxorg/ace/issues/5533)) ([f4d0e33](https://github.com/ajaxorg/ace/commit/f4d0e33dac270ce21df09a96a39f50e16d6354db)) + +## [1.34.0](https://github.com/ajaxorg/ace/compare/v1.33.3...v1.34.0) (2024-05-22) + + +### Features + +* allow users to add arialabel to text input ([#5560](https://github.com/ajaxorg/ace/issues/5560)) ([8d7dfb6](https://github.com/ajaxorg/ace/commit/8d7dfb69392960aba61def982f4bea8f3a5caa70)) + +### [1.33.3](https://github.com/ajaxorg/ace/compare/v1.33.2...v1.33.3) (2024-05-21) + + +### Bug Fixes + +* contrast completion meta contrast cloud editor themes ([#5558](https://github.com/ajaxorg/ace/issues/5558)) ([b8877f0](https://github.com/ajaxorg/ace/commit/b8877f0f725b3973961cb639127402c9f56609de)) + +### [1.33.2](https://github.com/ajaxorg/ace/compare/v1.33.1...v1.33.2) (2024-05-13) + + +### Bug Fixes + +* Add soft wrap for ghost text ([#5540](https://github.com/ajaxorg/ace/issues/5540)) ([6a26b27](https://github.com/ajaxorg/ace/commit/6a26b277d0050b38cd766e00f93be4b9f3170f68)) +* generator function's determination; wrong parameter highlighting ([#5538](https://github.com/ajaxorg/ace/issues/5538)) ([ceca6f7](https://github.com/ajaxorg/ace/commit/ceca6f7b38f6b3347988f17579ae6a2e758137dd)) +* incorrect spans style ([#5539](https://github.com/ajaxorg/ace/issues/5539)) ([65a7f38](https://github.com/ajaxorg/ace/commit/65a7f38713cffb729dab530711351c0a17c5801f)) +* not determined folding widgets for html tags ([#5548](https://github.com/ajaxorg/ace/issues/5548)) ([7a51992](https://github.com/ajaxorg/ace/commit/7a5199292f55dfa1a8ea8830ea1a9d98be097161)) +* wrong token type ([#5535](https://github.com/ajaxorg/ace/issues/5535)) ([4041489](https://github.com/ajaxorg/ace/commit/4041489bb38ffe609d5f9b43b4a7637e47fc4739)) + +### [1.33.1](https://github.com/ajaxorg/ace/compare/v1.33.0...v1.33.1) (2024-04-23) + + +### Bug Fixes + +* 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)) + +## [1.33.0](https://github.com/ajaxorg/ace/compare/v1.32.9...v1.33.0) (2024-04-12) + + +### Features + +* 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)) + + +### Bug Fixes + +* Contrast is too low for searched items ([#5523](https://github.com/ajaxorg/ace/issues/5523)) ([507ae2f](https://github.com/ajaxorg/ace/commit/507ae2f872a2b2f1a14fdffbf6530f4046df44c0)) + +### [1.32.9](https://github.com/ajaxorg/ace/compare/v1.32.8...v1.32.9) (2024-03-29) + + +### Bug Fixes + +* 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)) + +### [1.32.8](https://github.com/ajaxorg/ace/compare/v1.32.7...v1.32.8) (2024-03-22) + + +### Bug Fixes + +* allow completers to trigger on newline characters ([#5519](https://github.com/ajaxorg/ace/issues/5519)) ([6e870fd](https://github.com/ajaxorg/ace/commit/6e870fd08e06be47f9da971743d13b25c41f99c2)) +* 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)) +* 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)) +* SwiftHighlightRules exports ([#5516](https://github.com/ajaxorg/ace/issues/5516)) ([f493ab0](https://github.com/ajaxorg/ace/commit/f493ab03bb50fe089c927b7a50a4a327c8dcec4c)) + +### [1.32.7](https://github.com/ajaxorg/ace/compare/v1.32.6...v1.32.7) (2024-03-01) + + +### Bug Fixes + +* 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)) + +### [1.32.6](https://github.com/ajaxorg/ace/compare/v1.32.5...v1.32.6) (2024-02-07) + +### [1.32.5](https://github.com/ajaxorg/ace/compare/v1.32.4...v1.32.5) (2024-01-30) + +### [1.32.4](https://github.com/ajaxorg/ace/compare/v1.32.3...v1.32.4) (2024-01-29) + + +### Bug Fixes + +* Improve contrast of completion popup in CloudEditor theme ([#5473](https://github.com/ajaxorg/ace/issues/5473)) ([273c7f1](https://github.com/ajaxorg/ace/commit/273c7f159ded7dc9403266c6501e16a35e4101c6)) +* update JSX mode to reflect React JSX ([#5451](https://github.com/ajaxorg/ace/issues/5451)) ([66789a7](https://github.com/ajaxorg/ace/commit/66789a79ce1b7791c65886d8aecddd7efc0415e8)) + +### [1.32.3](https://github.com/ajaxorg/ace/compare/v1.32.2...v1.32.3) (2023-12-29) + + +### Bug Fixes + +* improve prefixing for inline preview ([#5439](https://github.com/ajaxorg/ace/issues/5439)) ([51006bb](https://github.com/ajaxorg/ace/commit/51006bba9c60b97251ddb04ed74f68ba4e7f6b54)) +* update ghost text if on same line popup ([12f4664](https://github.com/ajaxorg/ace/commit/12f466460d7187cfe37593dab1fbe275403fedd3)) +* updated red color in cloud-editor dark theme ([#5432](https://github.com/ajaxorg/ace/issues/5432)) ([142b607](https://github.com/ajaxorg/ace/commit/142b607578f5d071a5026691ff6662c11e9f186b)) + +### [1.32.2](https://github.com/ajaxorg/ace/compare/v1.32.1...v1.32.2) (2023-12-14) + + +### Bug Fixes + +* **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) + +### [1.32.1](https://github.com/ajaxorg/ace/compare/v1.32.0...v1.32.1) (2023-12-11) + + +### Bug Fixes + +* don't show loading state when empty completer array is provided ([7a8a929](https://github.com/ajaxorg/ace/commit/7a8a92933b3fde75907612d106643d28efa2d776)) +* prevent browser scroll while scrolling over the tooltip ([#5414](https://github.com/ajaxorg/ace/issues/5414)) ([c6475c0](https://github.com/ajaxorg/ace/commit/c6475c00bcfa49dde37ef9de06ebba82ba5ba15d)) +* 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) +* yaml worker errors at undefined row/column ([06cc12a](https://github.com/ajaxorg/ace/commit/06cc12aad98176d931a1c1cf9a701f4ac0c33de5)) + +## [1.32.0](https://github.com/ajaxorg/ace/compare/v1.31.2...v1.32.0) (2023-11-30) + + +### Features + +* adding CloudEditor theme ([#5404](https://github.com/ajaxorg/ace/issues/5404)) ([b0ee067](https://github.com/ajaxorg/ace/commit/b0ee067fadaf9593ed2207f363a402eb9ab8d57a)) + + +### Bug Fixes + +* autocomplete tests ([#5407](https://github.com/ajaxorg/ace/issues/5407)) ([cf6999d](https://github.com/ajaxorg/ace/commit/cf6999d9cb4103df16dc38a8cbfd40ab2a999e6d)) +* set completion popup role to 'menu' for safari ([6845905](https://github.com/ajaxorg/ace/commit/684590546746fa2ef090c10c140e01e43974d8f4)) +* 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)) +* try to scroll inline preview into view ([#5400](https://github.com/ajaxorg/ace/issues/5400)) ([95af560](https://github.com/ajaxorg/ace/commit/95af5608b655259d12cdbc4ca28cf450f9e649c7)) + +### [1.31.2](https://github.com/ajaxorg/ace/compare/v1.31.1...v1.31.2) (2023-11-15) + + +### Bug Fixes + +* inline preview with loading state ([05db94f](https://github.com/ajaxorg/ace/commit/05db94f53774f64318de757347f7217043744fe6)) + +### [1.31.1](https://github.com/ajaxorg/ace/compare/v1.31.0...v1.31.1) (2023-10-30) + + +### Bug Fixes + +* improve yaml folding ([5c80e3c](https://github.com/ajaxorg/ace/commit/5c80e3cdd716b4ad26ee6958c9137278530b7816)) + +## [1.31.0](https://github.com/ajaxorg/ace/compare/v1.30.0...v1.31.0) (2023-10-23) + + +### Features + +* add nasal language ([#5342](https://github.com/ajaxorg/ace/issues/5342)) ([4fff99e](https://github.com/ajaxorg/ace/commit/4fff99e320539a1472ce0512cd1fd3e5fc7f2ca6)) + + +### Bug Fixes + +* doc tooltip not filtering properly ([e5034c7](https://github.com/ajaxorg/ace/commit/e5034c7b58fb47fe57b28dbb001e72a567ef9abe)) + +## [1.30.0](https://github.com/ajaxorg/ace/compare/v1.29.0...v1.30.0) (2023-10-13) + + +### Features + +* Add support for time units in PRQL ([#5324](https://github.com/ajaxorg/ace/issues/5324)) ([8b9175b](https://github.com/ajaxorg/ace/commit/8b9175bc780fade64bed1570fa1cd34d022b337b)) + +## [1.29.0](https://github.com/ajaxorg/ace/compare/v1.28.0...v1.29.0) (2023-10-09) + + +### Features + +* allow setting completion.ignoreCaption ([5618046](https://github.com/ajaxorg/ace/commit/56180467e12c300850da89cc13c1c8648fb5e342)) + +## [1.28.0](https://github.com/ajaxorg/ace/compare/v1.27.0...v1.28.0) (2023-09-22) + + +### Features + +* 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)) + +## [1.27.0](https://github.com/ajaxorg/ace/compare/v1.26.0...v1.27.0) (2023-09-19) + + +### Features + +* 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)) + +## [1.26.0](https://github.com/ajaxorg/ace/compare/v1.25.1...v1.26.0) (2023-09-15) + + +### Features + +* Allow to set setSelectOnHover for Autocomplete ([#5317](https://github.com/ajaxorg/ace/issues/5317)) ([dccbcc2](https://github.com/ajaxorg/ace/commit/dccbcc20288a48403f10aa29b6b9b6181dc8a66f)) + + +### Bug Fixes + +* Improve PRQL syntax highlightning ([#5313](https://github.com/ajaxorg/ace/issues/5313)) ([7d677f1](https://github.com/ajaxorg/ace/commit/7d677f1019ea5c81f3d9ae36ed1e71ac7a08fb30)) + +### [1.25.1](https://github.com/ajaxorg/ace/compare/v1.25.0...v1.25.1) (2023-09-14) + +## [1.25.0](https://github.com/ajaxorg/ace/compare/v1.24.2...v1.25.0) (2023-09-14) + + +### Features + +* Add syntax highlighting for PRQL ([#5307](https://github.com/ajaxorg/ace/issues/5307)) ([24862cd](https://github.com/ajaxorg/ace/commit/24862cdc83694bbe541c6f8be6fbaaff80d44bf7)) + +### [1.24.2](https://github.com/ajaxorg/ace/compare/v1.24.1...v1.24.2) (2023-09-08) + + +### Bug Fixes + +* Added project details in index.html file ([#5300](https://github.com/ajaxorg/ace/issues/5300)) ([6e83505](https://github.com/ajaxorg/ace/commit/6e835059dd13e95178b15ce9b06a2f2444c2e731)) +* autocompletion threshold doesn't apply to trigger characters ([84bbc88](https://github.com/ajaxorg/ace/commit/84bbc888e1c0304c0160bb19fc46cf5539d079cf)) +* Update php_highlight_rules.js ([#5288](https://github.com/ajaxorg/ace/issues/5288)) ([caedd0c](https://github.com/ajaxorg/ace/commit/caedd0cf22d5a7644ceb418562ebcab801011c88)) + +### [1.24.1](https://github.com/ajaxorg/ace/compare/v1.24.0...v1.24.1) (2023-08-15) + +## [1.24.0](https://github.com/ajaxorg/ace/compare/v1.23.4...v1.24.0) (2023-08-09) + + +### Features + +* Add support for Unicode boundaries ([#5265](https://github.com/ajaxorg/ace/issues/5265)) ([1e6fcf3](https://github.com/ajaxorg/ace/commit/1e6fcf349d222715429ddc9fe6a38ec1f6d72ab1)) +* 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)) +* Cuttlefish mode ([#5278](https://github.com/ajaxorg/ace/issues/5278)) ([9cddf64](https://github.com/ajaxorg/ace/commit/9cddf64ac51fc5e7c5474e7aeaa2ef8f069220db)) + + +### Bug Fixes + +* add missing SQL keywords: IS and IN ([#5263](https://github.com/ajaxorg/ace/issues/5263)) ([c731164](https://github.com/ajaxorg/ace/commit/c731164315a757a5e0380f82eeef105a17b24b03)) +* bug in lua.lua example file kitchen-sink ([#5258](https://github.com/ajaxorg/ace/issues/5258)) ([6549570](https://github.com/ajaxorg/ace/commit/6549570310983999a1fd3ce52bc5bf8b4004402f)) +* support more environments ([#5266](https://github.com/ajaxorg/ace/issues/5266)) ([b196806](https://github.com/ajaxorg/ace/commit/b196806eb2937e7ee56e42b482b7b3bd5e3c9d79)) + +### [1.23.4](https://github.com/ajaxorg/ace/compare/v1.23.3...v1.23.4) (2023-07-12) + + +### Bug Fixes + +* 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)) + +### [1.23.3](https://github.com/ajaxorg/ace/compare/v1.23.2...v1.23.3) (2023-07-10) + + +### Bug Fixes + +* 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) +* 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)) + +### [1.23.2](https://github.com/ajaxorg/ace/compare/v1.23.1...v1.23.2) (2023-07-07) + + +### Bug Fixes + +* **autocomplete:** fix a11y violations ([#5241](https://github.com/ajaxorg/ace/issues/5241)) ([decb615](https://github.com/ajaxorg/ace/commit/decb6154198105289170303b7434c524eaf9fda8)) +* bug in guttertooltip when `tooltipsFollowsMouse` set to false ([#5217](https://github.com/ajaxorg/ace/issues/5217)) ([67d318e](https://github.com/ajaxorg/ace/commit/67d318ed25d5b45789462850e6b96aac2931591f)) +* typo in function name ([#5229](https://github.com/ajaxorg/ace/issues/5229)) ([6e99055](https://github.com/ajaxorg/ace/commit/6e99055c46f443271161e40fe15372d1d8ae9f42)) + +### [1.23.1](https://github.com/ajaxorg/ace/compare/v1.23.0...v1.23.1) (2023-06-27) + +## [1.23.0](https://github.com/ajaxorg/ace/compare/v1.22.1...v1.23.0) (2023-06-21) + + +### Features + +* **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)) +* signal gutterkeydown in keyboard accessibility mode ([#5202](https://github.com/ajaxorg/ace/issues/5202)) ([538b18c](https://github.com/ajaxorg/ace/commit/538b18cf86e21c810910d286c820bac399927cd7)) + + +### Bug Fixes + +* Fix vite build and webpack warning ([#5192](https://github.com/ajaxorg/ace/issues/5192)) ([e14902e](https://github.com/ajaxorg/ace/commit/e14902e0c2b281346d062d6a5c84d05bd3590fe3)) +* gutter tooltip class fix ([#5211](https://github.com/ajaxorg/ace/issues/5211)) ([5bdb944](https://github.com/ajaxorg/ace/commit/5bdb944714e7787632914aeef521e3e5024a1d1f)) +* Improve ARIA labelling fold controls ([#5205](https://github.com/ajaxorg/ace/issues/5205)) ([dad5e6f](https://github.com/ajaxorg/ace/commit/dad5e6f6e445b805f7b470ef7892442a83d342e5)) +* regression in setting breakpoints on folded lines ([51326eb](https://github.com/ajaxorg/ace/commit/51326ebfe9b3e97925ab1be05246e0f2646c8687)) + +### [1.22.1](https://github.com/ajaxorg/ace/compare/v1.22.0...v1.22.1) (2023-06-11) + + +### Bug Fixes + +* 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)) +* include ace-modes to the npm package ([a074fa4](https://github.com/ajaxorg/ace/commit/a074fa41334314169075b66cd77dd2d9a191c73f)) +* jsdoc comment foldings ([#5197](https://github.com/ajaxorg/ace/issues/5197)) ([065af41](https://github.com/ajaxorg/ace/commit/065af4175f7c7426c9e8f798a0ec64c390a03259)) + +## [1.22.0](https://github.com/ajaxorg/ace/compare/v1.21.1...v1.22.0) (2023-05-22) + + +### Features + +* add odin mode ([#5169](https://github.com/ajaxorg/ace/issues/5169)) ([d455e9b](https://github.com/ajaxorg/ace/commit/d455e9b16efb6030a8b0b6c1189b72516b205b40)) + +### [1.21.1](https://github.com/ajaxorg/ace/compare/v1.21.0...v1.21.1) (2023-05-16) + + +### Bug Fixes + +* 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)) + +## [1.21.0](https://github.com/ajaxorg/ace/compare/v1.20.0...v1.21.0) (2023-05-15) + + +### Features + +* Custom empty message when no completion found ([#5158](https://github.com/ajaxorg/ace/issues/5158)) ([204aafa](https://github.com/ajaxorg/ace/commit/204aafa04c268e98655fb83b4877302a0f82fa4d)) +* Special trigger characters to start autocomplete ([#5147](https://github.com/ajaxorg/ace/issues/5147)) ([c2cfc5a](https://github.com/ajaxorg/ace/commit/c2cfc5a9f1448f64e62f7652c995a48c4ea31ab3)) + + +### Bug Fixes + +* command bar command type ([#5168](https://github.com/ajaxorg/ace/issues/5168)) ([64c8253](https://github.com/ajaxorg/ace/commit/64c8253e3cd4348b7ecd3684dae057c8fd5f79b9)) + +## [1.20.0](https://github.com/ajaxorg/ace/compare/v1.19.0...v1.20.0) (2023-05-10) + + +### Features + +* Add gutter controls to keyboard accessibility mode ([#5146](https://github.com/ajaxorg/ace/issues/5146)) ([5f2face](https://github.com/ajaxorg/ace/commit/5f2face8febe7c260a42bc30c67195f6a5a46085)) +* Inline autocomplete tooltip UX redesign ([#5149](https://github.com/ajaxorg/ace/issues/5149)) ([8d56c84](https://github.com/ajaxorg/ace/commit/8d56c841ef980527a1ebe4cf73442766f5f97208)) + +## [1.19.0](https://github.com/ajaxorg/ace/compare/v1.18.1...v1.19.0) (2023-05-03) + + +### Features + +* publishing generated styling files to ace-code package ([1fa223e](https://github.com/ajaxorg/ace/commit/1fa223e4ca0df16c9a0e0a6df2996fa010189666)) + +### [1.18.1](https://github.com/ajaxorg/ace/compare/v1.18.0...v1.18.1) (2023-05-03) + + +### Bug Fixes + +* add mode types, improve type definitions ([e22bd5c](https://github.com/ajaxorg/ace/commit/e22bd5c860451c000187941991c0047db4e701a2)) +* hide `$getindent` from the SyntaxMode ([2b1c65b](https://github.com/ajaxorg/ace/commit/2b1c65bceb290db74f26a5c59158f93830bc6111)) +* remove '$' fields for types that don't require exposing them ([2db9d4e](https://github.com/ajaxorg/ace/commit/2db9d4e88441f2932ce6c6f91e7f5ed36c590d2f)) +* remove or update badly formatted declarations ([1e7b022](https://github.com/ajaxorg/ace/commit/1e7b022908cdf6fef0a28419c464874ce6433e6e)) +* 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)) +* wrong next state in regex state ([c5ed709](https://github.com/ajaxorg/ace/commit/c5ed7092f0151d4aa00c7060ecf0111fc37bfebb)) + +## [1.18.0](https://github.com/ajaxorg/ace/compare/v1.17.0...v1.18.0) (2023-04-21) + + +### Features + +* marker groups ([#5113](https://github.com/ajaxorg/ace/issues/5113)) ([01d4605](https://github.com/ajaxorg/ace/commit/01d4605c0dcf7bcbb4f1a09a243f7ef6d16d7d43)) +* summary of annotations in folded lines ([#5117](https://github.com/ajaxorg/ace/issues/5117)) ([dc63ba9](https://github.com/ajaxorg/ace/commit/dc63ba900d3641284d7d11cbb5ccad7c3039f3a4)) + +## [1.17.0](https://github.com/ajaxorg/ace/compare/v1.16.0...v1.17.0) (2023-04-12) + + +### Features + +* Add annotation level information to gutter tooltip ([#5101](https://github.com/ajaxorg/ace/issues/5101)) ([3cd28b8](https://github.com/ajaxorg/ace/commit/3cd28b88a51176c791e045f405cdf842916697ab)) +* Add option to prevent keyboard focus trapping ([#5114](https://github.com/ajaxorg/ace/issues/5114)) ([fe5d1bf](https://github.com/ajaxorg/ace/commit/fe5d1bfbf0a3432b78a5e503d1db680181ef48b8)) +* Add option to use SVG gutter icons ([#5107](https://github.com/ajaxorg/ace/issues/5107)) ([82eb439](https://github.com/ajaxorg/ace/commit/82eb439709773a71515fbe97c4e89890ea77e752)) +* add ResizeObserver to make calling editor.resize optional ([51d5e4d](https://github.com/ajaxorg/ace/commit/51d5e4d4308ba98921b1d6ea8cf946d0e17d0a7a)) + + +### Bug Fixes + +* adds missing 'on' method for 'guttermousedown' ([7212042](https://github.com/ajaxorg/ace/commit/721204292907549fd4fd02d6672afd2b63d1e168)) +* 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)) +* Improves Liquid Support ([#5098](https://github.com/ajaxorg/ace/issues/5098)) ([0ae8dbb](https://github.com/ajaxorg/ace/commit/0ae8dbb0fe017cfb8321307e5bfe5959eb121754)) + +## [1.16.0](https://github.com/ajaxorg/ace/compare/v1.14.0...v1.16.0) (2023-03-17) + + +### Features + +* Added Editor API to set the ghost text ([#5036](https://github.com/ajaxorg/ace/issues/5036)) ([958d573](https://github.com/ajaxorg/ace/commit/958d57383c4ebfacd414eb817aecc2e0982d1b36)) +* Inline autocompletion ([#5084](https://github.com/ajaxorg/ace/issues/5084)) ([eb834a1](https://github.com/ajaxorg/ace/commit/eb834a1f1ca7f922437a90f2f14d935d75f31ac8)) + + +### Bug Fixes + +* add updated monospace font for Windows ([#5091](https://github.com/ajaxorg/ace/issues/5091)) ([a981972](https://github.com/ajaxorg/ace/commit/a9819722cec6ff60b028deaa7b70d7fefabac531)) +* 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)) +* 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)) +* 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)) +* 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) +* Implement highlight mode for PL/SQL (Oracle) dialect ([#5037](https://github.com/ajaxorg/ace/issues/5037)) ([159aa70](https://github.com/ajaxorg/ace/commit/159aa70d551530f2866fb0006fad37bd75e60dda)) +* Improve MySQL highlighting mode ([#5050](https://github.com/ajaxorg/ace/issues/5050)) ([00f6089](https://github.com/ajaxorg/ace/commit/00f60890a36121d7c705445514dcf79a81055f55)) +* 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) +* Remove broken keybinding from vscode mode ([#5032](https://github.com/ajaxorg/ace/issues/5032)) ([68ff964](https://github.com/ajaxorg/ace/commit/68ff964a214cc2da66e4a35b313ff66dd4490e34)) + +### [1.15.3](https://github.com/ajaxorg/ace/compare/v1.15.2...v1.15.3) (2023-03-02) + +### [1.15.2](https://github.com/ajaxorg/ace/compare/v1.15.1...v1.15.2) (2023-02-16) + +### [1.15.1](https://github.com/ajaxorg/ace/compare/v1.15.0...v1.15.1) (2023-02-13) + + +### Bug Fixes + +* 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)) +* Implement highlight mode for PL/SQL (Oracle) dialect ([#5037](https://github.com/ajaxorg/ace/issues/5037)) ([159aa70](https://github.com/ajaxorg/ace/commit/159aa70d551530f2866fb0006fad37bd75e60dda)) +* Improve MySQL highlighting mode ([#5050](https://github.com/ajaxorg/ace/issues/5050)) ([00f6089](https://github.com/ajaxorg/ace/commit/00f60890a36121d7c705445514dcf79a81055f55)) + +## [1.15.0](https://github.com/ajaxorg/ace/compare/v1.14.0...v1.15.0) (2023-01-25) + + +### Features + +* Added Editor API to set the ghost text ([#5036](https://github.com/ajaxorg/ace/issues/5036)) ([958d573](https://github.com/ajaxorg/ace/commit/958d57383c4ebfacd414eb817aecc2e0982d1b36)) + + +### Bug Fixes + +* 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)) +* 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)) +* Remove broken keybinding from vscode mode ([#5032](https://github.com/ajaxorg/ace/issues/5032)) ([68ff964](https://github.com/ajaxorg/ace/commit/68ff964a214cc2da66e4a35b313ff66dd4490e34)) + +## [1.14.0](https://github.com/ajaxorg/ace/compare/v1.13.1...v1.14.0) (2022-12-12) + + +### Features + +* Autocomplete accessibility features ([#5008](https://github.com/ajaxorg/ace/issues/5008)) ([3b7bb5e](https://github.com/ajaxorg/ace/commit/3b7bb5e4afbad0f2bdbc7f8487442a5cb78b8284)) + + +### Bug Fixes + +* Add missing options to `EditorOptions` ([#5003](https://github.com/ajaxorg/ace/issues/5003)) ([451b63f](https://github.com/ajaxorg/ace/commit/451b63f2243762d6de2fc5b9ee8c580c348b933c)) +* 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)) +* Better ES6 support for JavaScript Mode ([6fb39e3](https://github.com/ajaxorg/ace/commit/6fb39e38c79dd966233e48ed06be800c59c4c101)) +* Fix vim keybindings scroll to the selected line ([#4980](https://github.com/ajaxorg/ace/issues/4980)) ([8562f94](https://github.com/ajaxorg/ace/commit/8562f9493e0ebef865064992f0526fdc6df8535a)) +* 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)) +* Update ace.d.ts typings for navigate ([#5011](https://github.com/ajaxorg/ace/issues/5011)) ([a302709](https://github.com/ajaxorg/ace/commit/a30270990cc0041edb6985059915f96524ebb154)) + +### [1.13.2](https://github.com/ajaxorg/ace/compare/v1.13.1...v1.13.2) (2022-12-07) + + +### Bug Fixes + +* Add missing options to `EditorOptions` ([#5003](https://github.com/ajaxorg/ace/issues/5003)) ([451b63f](https://github.com/ajaxorg/ace/commit/451b63f2243762d6de2fc5b9ee8c580c348b933c)) +* Better ES6 support for JavaScript Mode ([6fb39e3](https://github.com/ajaxorg/ace/commit/6fb39e38c79dd966233e48ed06be800c59c4c101)) +* Fix vim keybindings scroll to the selected line ([#4980](https://github.com/ajaxorg/ace/issues/4980)) ([8562f94](https://github.com/ajaxorg/ace/commit/8562f9493e0ebef865064992f0526fdc6df8535a)) +* 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)) + +### [1.13.1](https://github.com/ajaxorg/ace/compare/v1.13.0...v1.13.1) (2022-11-16) + + +### Bug Fixes + +* 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)) +* incorrect cursor position for very long lines ([#4996](https://github.com/ajaxorg/ace/issues/4996)) ([e57a9d9](https://github.com/ajaxorg/ace/commit/e57a9d9eef0c056cd38a07c77c460bea39cc9551)) + +## [1.13.0](https://github.com/ajaxorg/ace/compare/v1.12.5...v1.13.0) (2022-11-11) + + +### Features + +* add highlight mode for Apache JEXL ([#4979](https://github.com/ajaxorg/ace/issues/4979)) ([4e8926e](https://github.com/ajaxorg/ace/commit/4e8926ef9f9207e57529e07cdbe2305b09e712e2)) + + +### Bug Fixes + +* Add missing options to `VirtualRendererOptions` and `EditorOptions` ([#4983](https://github.com/ajaxorg/ace/issues/4983)) ([19dd2ec](https://github.com/ajaxorg/ace/commit/19dd2ecc178bef2fedd6a53900f2db58ea7a3c23)) +* Fix of scroll while interrupting animation ([#4993](https://github.com/ajaxorg/ace/issues/4993)) ([0092f3f](https://github.com/ajaxorg/ace/commit/0092f3f8c1f0d9c8a0b8bebe58cc3517931697b7)) +* 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)) + +### [1.12.5](https://github.com/ajaxorg/ace/compare/v1.12.4...v1.12.5) (2022-11-01) + + +### Bug Fixes + +* enableLiveAutocompletion documentation ([#4976](https://github.com/ajaxorg/ace/issues/4976)) ([987ab76](https://github.com/ajaxorg/ace/commit/987ab7602e06acc9b08c75914f5c1335d5cdc8cc)) +* vim "normal" mode brackets highlighting ([0fbc54c](https://github.com/ajaxorg/ace/commit/0fbc54cc5130b0271928995660413ba0fab678cb)) + +### [1.12.4](https://github.com/ajaxorg/ace/compare/v1.12.3...v1.12.4) (2022-10-31) + + +### Bug Fixes + +* Open valid url under cursor ([#4970](https://github.com/ajaxorg/ace/issues/4970)) ([bf2913a](https://github.com/ajaxorg/ace/commit/bf2913a71624e94d13727115b2aa0ef0c279c89f)) +* Update for Csound 6.18.0 ([#4974](https://github.com/ajaxorg/ace/issues/4974)) ([6886b02](https://github.com/ajaxorg/ace/commit/6886b0233e9e1d8d6cce5d3ade7b27fe4527c940)) +* update/add missing demo samples ([#4975](https://github.com/ajaxorg/ace/issues/4975)) ([2b8236e](https://github.com/ajaxorg/ace/commit/2b8236eaf1df10caa9ff45a06902df14947cd968)) + +### [1.12.3](https://github.com/ajaxorg/ace/compare/v1.12.2...v1.12.3) (2022-10-18) + + +### Bug Fixes + +* Fix syntax error in the custom scroll CSS ([#4968](https://github.com/ajaxorg/ace/issues/4968)) ([f2a424a](https://github.com/ajaxorg/ace/commit/f2a424a649f655b9511b1bb6047097634edb0e3f)) + +### [1.12.2](https://github.com/ajaxorg/ace/compare/v1.12.1...v1.12.2) (2022-10-18) + + +### Bug Fixes + +* custom scrollbar breaks csp mode ([#4967](https://github.com/ajaxorg/ace/issues/4967)) ([be8eb12](https://github.com/ajaxorg/ace/commit/be8eb1236fb7e1d27cedf033d301f094ec6764e5)) +* find all in range bug ([13bd553](https://github.com/ajaxorg/ace/commit/13bd55348dc8de5c547c74ec0e48c52b6db96a26)) +* Namespace-relative names for php ([#4963](https://github.com/ajaxorg/ace/issues/4963)) ([96e4066](https://github.com/ajaxorg/ace/commit/96e4066341fb7b82d02ad8272929711073d3bfc4)) + +### [1.12.1](https://github.com/ajaxorg/ace/compare/v1.12.0...v1.12.1) (2022-10-17) + + +### Bug Fixes + +* php worker rules for T_NAME_FULLY_QUALIFIED ([#4960](https://github.com/ajaxorg/ace/issues/4960)) ([52dbb05](https://github.com/ajaxorg/ace/commit/52dbb0577693e29f124a1f16008b4e11e2ce7c02)) +* recognisition of uppercase hex numbers for stylus mode ([#4962](https://github.com/ajaxorg/ace/issues/4962)) ([87e0dc7](https://github.com/ajaxorg/ace/commit/87e0dc7b868798300e874e39304aeda18d3d1a76)) + +## [1.12.0](https://github.com/ajaxorg/ace/compare/v1.11.2...v1.12.0) (2022-10-15) + + +### Features + +* implement BibTeX mode highlighting ([ab9e191](https://github.com/ajaxorg/ace/commit/ab9e1916cb3363260de58b808bdc21fd6bc01618)) + + +### Bug Fixes + +* `MockDom's` `ClassList` `toggle` and `contains` methods return `boolean` instead of `void` ([e8c0a1f](https://github.com/ajaxorg/ace/commit/e8c0a1f35d302966626896aaf84b056e76a8e66e)) +* change lua version to 5.3 ([#4954](https://github.com/ajaxorg/ace/issues/4954)) ([fc56af5](https://github.com/ajaxorg/ace/commit/fc56af5936a2ebfdfa0871ca6a68ccf7ecc7dbf0)) +* documentation for TokenIterator methods ([#4955](https://github.com/ajaxorg/ace/issues/4955)) ([6bff7b4](https://github.com/ajaxorg/ace/commit/6bff7b43c7ad34dd5fafc81c5de773e9d709026d)) +* 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)) +* mode change for vim tests ([236a31e](https://github.com/ajaxorg/ace/commit/236a31e5d69fd4fd874b667b38dd1bf0685f75c5)) +* 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)) +* tools to work with new ace project structure ([7894c4b](https://github.com/ajaxorg/ace/commit/7894c4bbc6da5eb3521efb3b89b1a189202c2497)) + +### [1.11.2](https://github.com/ajaxorg/ace/compare/v1.11.1...v1.11.2) (2022-09-26) + + +### Bug Fixes + +* Fixed handling surrogare characters in insert, replace, delete mode in Vim ([72fd4b7](https://github.com/ajaxorg/ace/commit/72fd4b7b616f070be198dc8fc437d48a74637a53)) +* Fixed handling surrogate characters in insert-after mode in Vim ([38f893a](https://github.com/ajaxorg/ace/commit/38f893a13b1f1dedea4407a8f3ef1d6098873269)) + +### [1.11.1](https://github.com/ajaxorg/ace/compare/v1.11.0...v1.11.1) (2022-09-23) + + +### Bug Fixes + +* 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)) +* The editor can be crashed by passing in undefined into the setValue method ([56e6e56](https://github.com/ajaxorg/ace/commit/56e6e56137ea5717009e3687019f64dae7f88da2)) +* Update vim mode ([#4933](https://github.com/ajaxorg/ace/issues/4933)) ([3b89ed0](https://github.com/ajaxorg/ace/commit/3b89ed06069cb45edb59b7442b5cc6c15b33cfa4)) + +## [1.11.0](https://github.com/ajaxorg/ace/compare/v1.10.1...v1.11.0) (2022-09-20) + + +### Features + +* add gutter indicators for annotations; add custom scrollbar to display gutter indicators ([62fb0d8](https://github.com/ajaxorg/ace/commit/62fb0d8fba813241d01356962ed20ac868a29ede)) + + +### Bug Fixes + +* change scroll behaviour for `onmousedown` to immediate scroll to point ([392b224](https://github.com/ajaxorg/ace/commit/392b224ceb4e82b4d906c36aef2ea4953e3d440e)) +* 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)) +* restrict annotation mark max height and optimise marks coords on canvas ([a6e2259](https://github.com/ajaxorg/ace/commit/a6e2259eb0a282c62fd9e6fde31d86b6c14ec06d)) + +### [1.10.1](https://github.com/ajaxorg/ace/compare/v1.10.0...v1.10.1) (2022-09-06) + + +### Bug Fixes + +* prevent javascript snippets file confusing old packagers ([#4917](https://github.com/ajaxorg/ace/issues/4917)) ([5d7b65c](https://github.com/ajaxorg/ace/commit/5d7b65c30aff0106a7001f68ecdf13a23893eaad)) + +## [1.10.0](https://github.com/ajaxorg/ace/compare/v1.9.6...v1.10.0) (2022-08-31) + + +### Features + +* editor option for indent guide highlighting ([f1f6517](https://github.com/ajaxorg/ace/commit/f1f6517a30d6819d1c8ca045744cdeb2925ccf0a)) + + +### Bug Fixes + +* add mock `getHighlightIndentGuides` and `setHighlightIndentGuides` for old tests to work ([4067512](https://github.com/ajaxorg/ace/commit/4067512a72934b23a0866eca33812425c37a7363)) +* added "flex-start" and "flex-end" ([#4912](https://github.com/ajaxorg/ace/issues/4912)) ([3e14988](https://github.com/ajaxorg/ace/commit/3e14988209354f94483307f168705690e15adaf5)) +* Fix problematic semicolon in CSS media queries ([#4849](https://github.com/ajaxorg/ace/issues/4849)) ([18a459a](https://github.com/ajaxorg/ace/commit/18a459a26430bfa58e0f798c4bacce6a799c77bd)) +* more optimal way to accessing an element's list of classes; mark `highlightIndentGuide` as internal property ([855a874](https://github.com/ajaxorg/ace/commit/855a874ffde4824bb8de6e56cb44fad64d49725b)) +* strictly equal instead of loosely ([d4c1ab8](https://github.com/ajaxorg/ace/commit/d4c1ab8ef6ee608e2570b7ca6d1d941c5a6628a9)) +* Updated Jshint to 2.13.5 ([#4911](https://github.com/ajaxorg/ace/issues/4911)) ([2401fbd](https://github.com/ajaxorg/ace/commit/2401fbd93f0d61cc01150c1071145e974dd6693f)) + +### [1.9.6](https://github.com/ajaxorg/ace/compare/v1.9.5...v1.9.6) (2022-08-17) + + +### Bug Fixes + +* better way to extract css for csp environments ([1b0612b](https://github.com/ajaxorg/ace/commit/1b0612b5a5ed33a2f1931e4aa08cb2d54ec8585c)) + +### [1.9.5](https://github.com/ajaxorg/ace/compare/v1.9.4...v1.9.5) (2022-08-10) + + +### Bug Fixes + +* 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)) + +### [1.9.4](https://github.com/ajaxorg/ace/compare/v1.9.2...v1.9.4) (2022-08-09) + +### [1.9.3](https://github.com/ajaxorg/ace/compare/v1.9.2...v1.9.3) (2022-08-08) + +### [1.9.2](https://github.com/ajaxorg/ace/compare/v1.9.1...v1.9.2) (2022-08-08) + +### [1.9.1](https://github.com/ajaxorg/ace/compare/v1.9.0...v1.9.1) (2022-08-08) + +## [1.9.0](https://github.com/ajaxorg/ace/compare/v1.8.1...v1.9.0) (2022-08-08) + + +### Features + +* added ability to limit amount of undos/redos ([#4872](https://github.com/ajaxorg/ace/issues/4872)) ([897ee0a](https://github.com/ajaxorg/ace/commit/897ee0a071ef4341338a285a1d9d8781fe5689de)) +* 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)) + + +### Bug Fixes + +* 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)) +* Fixed Ace typings ([23208f2](https://github.com/ajaxorg/ace/commit/23208f2f19020d1f69b90bc3b02460bda8422072)) +* Fixed jsDoc annotations ([e15abb4](https://github.com/ajaxorg/ace/commit/e15abb443abfad2de59c620ce49fc5498ce6d33e)), closes [#4879](https://github.com/ajaxorg/ace/issues/4879) +* refactor of kotlin mode to simplify states and resolve incorrect highlights ([a30a99d](https://github.com/ajaxorg/ace/commit/a30a99df731c2f10c2006181ca58a96e7fc21155)) +* returned precise highlight for functions params, generics and types ([967aa6b](https://github.com/ajaxorg/ace/commit/967aa6b05c4a69a5deac1b20c297648444ade7d6)) +* 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)) + +### [1.8.1](https://github.com/ajaxorg/ace/compare/v1.8.0...v1.8.1) (2022-07-21) + + +### Bug Fixes + +* prevent race condition when creating css files in build ([1777bfb](https://github.com/ajaxorg/ace/commit/1777bfb7dca4dcaf575293ac9cacbc284f692351)) + +## [1.8.0](https://github.com/ajaxorg/ace/compare/v1.7.1...v1.8.0) (2022-07-20) + + +### Features + +* Use mini require ([#4845](https://github.com/ajaxorg/ace/issues/4845)) ([b9fabd4](https://github.com/ajaxorg/ace/commit/b9fabd47c0765d40117809cd3978b95d593370fb)) + + +### Bug Fixes + +* add undocumented Target command ([62e8e9e](https://github.com/ajaxorg/ace/commit/62e8e9e4d3b21552dd83d454b7fd55d4981d096a)), closes [#4839](https://github.com/ajaxorg/ace/issues/4839) +* added NSIS 3.08 commands ([acad68c](https://github.com/ajaxorg/ace/commit/acad68cf92f5372257b061e300e31f71df9c62e9)), closes [#4838](https://github.com/ajaxorg/ace/issues/4838) +* **bidihandler:** check for undefined before access length property on `splits` variable ([457b657](https://github.com/ajaxorg/ace/commit/457b65748f331740ded529fd7bbd06b86819fa4e)) +* correct highlight of php heredoc strings with one word on line ([ae4564c](https://github.com/ajaxorg/ace/commit/ae4564c2961b006ca849625a0dee1093061eba5a)) +* Fixed typo in Nord Dark theme. ([#4843](https://github.com/ajaxorg/ace/issues/4843)) ([38bf666](https://github.com/ajaxorg/ace/commit/38bf6663f43be1c45bfba3dc68c4a4820fb2661d)) +* Move session.onChange and placeholder.onChange handlers to be first in the change event handler queue ([bcb51f2](https://github.com/ajaxorg/ace/commit/bcb51f2b2a2ba2e1f30ebf543d97e7450574763f)) +* reuse `getTargetDir` function ([b89c4db](https://github.com/ajaxorg/ace/commit/b89c4db3424687856ff9c9e732435c35438b0cb9)) +* type declarations ([a8830fc](https://github.com/ajaxorg/ace/commit/a8830fc83708a7e51053038f1c6d7fde23e82e9d)) + +### [1.7.1](https://github.com/ajaxorg/ace/compare/v1.7.0...v1.7.1) (2022-06-29) + + +### Bug Fixes + +* Fixed accessing properties when err is null in onerror handler ([3b62a07](https://github.com/ajaxorg/ace/commit/3b62a0713e68fd76bfa9c52fa2112b56888d2349)) +* Uncaught TypeError: Cannot read properties of undefined in worker code ([ce068ac](https://github.com/ajaxorg/ace/commit/ce068ac29f0056f6a10d0fc99181b8ba3e274cfe)) + +## [1.7.0](https://github.com/ajaxorg/ace/compare/v1.6.1...v1.7.0) (2022-06-28) + + +### Features + +* Add Robot Framework syntax highlighting ([773c0c5](https://github.com/ajaxorg/ace/commit/773c0c5d8b87fabb643d8c1e2053f536c53318e8)), closes [#4614](https://github.com/ajaxorg/ace/issues/4614) +* Added YAML language linter ([451f915](https://github.com/ajaxorg/ace/commit/451f915e645f8a172098316196ae2e029fc26aed)), closes [#3979](https://github.com/ajaxorg/ace/issues/3979) + + +### Bug Fixes + +* 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) +* adds ignore browserified dir to eslintignore ([56b591b](https://github.com/ajaxorg/ace/commit/56b591b49673fcd062fd53325f74629d4cf45e3f)) +* Allow setAnnotations to use custom className ([f505879](https://github.com/ajaxorg/ace/commit/f505879d0463a8b2781e0e7caaaa857444d51f85)), closes [#4362](https://github.com/ajaxorg/ace/issues/4362) +* Avoid substitutions when Webpack was introduced ([a540323](https://github.com/ajaxorg/ace/commit/a540323e933c6bad164bdc9f103d8de744ee1546)), closes [#4476](https://github.com/ajaxorg/ace/issues/4476) +* Highlighting DISTINCT keyword in SQL ([fb3820a](https://github.com/ajaxorg/ace/commit/fb3820a9c1624c49a149d388bf26aa3d504704bb)), closes [#4399](https://github.com/ajaxorg/ace/issues/4399) +* 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) + +### [1.6.1](https://github.com/ajaxorg/ace/compare/v1.6.0...v1.6.1) (2022-06-24) + + +### Bug Fixes + +* Highlight unicode characters in Python function and class names ([be6f2d1](https://github.com/ajaxorg/ace/commit/be6f2d125a8ffe70ceb336051da6a161ce9cf1bc)) +* Incorrect YAML syntax highlighting for version numbers with multiple periods ([049d761](https://github.com/ajaxorg/ace/commit/049d76131e6122f7397fb30cc341db34baaf2813)) +* 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)) + +## [1.6.0](https://github.com/ajaxorg/ace/compare/v1.5.3...v1.6.0) (2022-06-10) + + +### Bug Fixes + +* 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)) +* Autocomplete stopped working after upgrade to v1.5.2 ([48e6b60](https://github.com/ajaxorg/ace/commit/48e6b601ad5ae03a99a341843194c3854d2376c2)) +* Fix css EOF duplicate errors [#4816](https://github.com/ajaxorg/ace/issues/4816) ([48176f6](https://github.com/ajaxorg/ace/commit/48176f66c8ca0dd239968329b471f55b548ee467)) +* 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)) + +### [1.5.3](https://github.com/ajaxorg/ace/compare/v1.5.2...v1.5.3) (2022-05-31) + + +### Bug Fixes + +* 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)) + +### [1.5.2](https://github.com/ajaxorg/ace/compare/v1.5.1...v1.5.2) (2022-05-30) + + +### Bug Fixes + +* Added es6-shim library to fix old browsers ([#4720](https://github.com/ajaxorg/ace/issues/4720)) ([5ba71a0](https://github.com/ajaxorg/ace/commit/5ba71a0b8b0804d8cb385f7b2ee6b63e9bd1c3b8)) +* Added mockdom.before method ([#4724](https://github.com/ajaxorg/ace/issues/4724)) ([ffedba3](https://github.com/ajaxorg/ace/commit/ffedba3e18138d7739285d1a9b945d01d384948e)) +* Added support for cjs, mjs and log modes ([#4718](https://github.com/ajaxorg/ace/issues/4718)) ([375498a](https://github.com/ajaxorg/ace/commit/375498a12ff28cf955224baf60d242421817220d)) +* Adds missed functions into `php_completions.js` ([#4726](https://github.com/ajaxorg/ace/issues/4726)) ([7d5f4b8](https://github.com/ajaxorg/ace/commit/7d5f4b83f3ecc854e70f1508e9247e39ca9de30a)) +* 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)) +* 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)) +* Fixed popup CSS styling ([#4728](https://github.com/ajaxorg/ace/issues/4728)) ([045a3e6](https://github.com/ajaxorg/ace/commit/045a3e652ec37b1ab3b716cdf2bc24967a75eb77)) +* Fixed scrolling code lenses into view ([#4717](https://github.com/ajaxorg/ace/issues/4717)) ([710b14a](https://github.com/ajaxorg/ace/commit/710b14a7709d7499a4d182ad707b3cbbb6e73a64)) +* Multiple improvements for Ace themes ([#4715](https://github.com/ajaxorg/ace/issues/4715)) ([87ad55d](https://github.com/ajaxorg/ace/commit/87ad55daf243bdc619e15fbf220dc5ded235ed4c)) +* 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)) +* Pass additional arguments for command.exec ([#4723](https://github.com/ajaxorg/ace/issues/4723)) ([3b36762](https://github.com/ajaxorg/ace/commit/3b36762c045246efbc2e11eaa08d20a90142d26f)) +* Removed focussing after timeout in text input ([#4716](https://github.com/ajaxorg/ace/issues/4716)) ([f8ea48f](https://github.com/ajaxorg/ace/commit/f8ea48f1fe6362696ed30e01030e75c117ce4323)) +* 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)) +* Updated ace typings ([#4714](https://github.com/ajaxorg/ace/issues/4714)) ([d5d6f9a](https://github.com/ajaxorg/ace/commit/d5d6f9a32ad443d02aa89d9f140917637f5f52ab)) + +### [1.5.1](https://github.com/ajaxorg/ace/compare/v1.5.0...v1.5.1) (2022-05-23) + + +### Bug Fixes + +* 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)) +* 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)) +* Multiple Partiql and Amazon Ion textual notation fixes ([#4686](https://github.com/ajaxorg/ace/issues/4686)) ([bffba8d](https://github.com/ajaxorg/ace/commit/bffba8d934773bc9236d741f1a1ce2237a971b3e)) +* 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)) +* Python functions should be highlighted as functions ([#4708](https://github.com/ajaxorg/ace/issues/4708)) ([b2aaf1f](https://github.com/ajaxorg/ace/commit/b2aaf1f5644397959bd8c94e9e705da176242edd)) +* Updated PHP mode to support PHP8.1 syntax ([#4696](https://github.com/ajaxorg/ace/issues/4696)) ([33cf1c6](https://github.com/ajaxorg/ace/commit/33cf1c66af970edaf7eb0a468276fca249b8a5c8)) + +## [1.5.0](https://github.com/ajaxorg/ace/compare/v1.4.14...v1.5.0) (2022-05-12) + + +### Features + +* Added ability to configure certain format options for beautify extension ([20275de](https://github.com/ajaxorg/ace/commit/20275de79c40636d27d5ce293cf528c915338fbd)) + + +### Bug Fixes + +* Modify syntax ([b78d772](https://github.com/ajaxorg/ace/commit/b78d77240e1909b9d91fcd2ac35a4c17af05f56b)) +* Render bidirectional unicode characters as control characters ([#4693](https://github.com/ajaxorg/ace/issues/4693)) ([4d2ecf0](https://github.com/ajaxorg/ace/commit/4d2ecf08afeb1556f2511a1423729c2549802da8)) + +2022.01.26 Version 1.4.14 + +- update vim mode +- remove slow regex in beautify extension + + 2021.09.30 Version 1.4.13 + +- added useStrictCSP global option to use in environments where dynamic style creation is disabled + see demo/csp.html for an example of a page which loads external css files instead of generating styles with javascript +- updated vim mode, added support for gqq command + + 2020.07.06 Version 1.4.12 + +- removed unused es5-shim +- imporved ruby and vbscript highlighting and folding +- workaround for double space being converted to dot on mobile keyboards + + 2020.04.15 Version 1.4.10 + +- added workaround for chrome bug causing memory leak after calling editor.destroy +- added code folding support for vbscript mode + + 2020.04.01 Version 1.4.9 + +- added option to disable autoindent +- added new language modes +- fixed backspace not working with some mobile keyboards + + 2020.01.14 Version 1.4.8 + +- highlight both matched braces, and highlight unmatched brace in red +- improve snippet manager +- compatibility with webpack file-loader v5 +- improve vim mode + + 2019.10.17 Version 1.4.7 + +- add placeholder option + + 2019.09.08 Version 1.4.6 + +- restore native behavior of ctrl-p on mac (jumptomatching command is moved to cmd-\) +- improve snippet manager +- fix backspace handling on mobile + + 2019.06.17 Version 1.4.5 + +- improve scrolling and selection on mobile +- improve type definitions + + 2019.04.24 Version 1.4.4 + +- add experimental command prompt +- add chrystal, nim and nginx highlight rules +- fix regression in vim mode on ios + + 2019.02.21 Version 1.4.3 + +- add sublime keybindings +- add rtl option +- implement ` and < textobjects in vim mode + + 2018.11.21 Version 1.4.2 + +- fix regression in vim mode +- improve keyboard input handling on ipad and IE +- add new syntax highlighters + + 2018.08.07 Version 1.4.1 + +- fix regression in autocomplete + + 2018.08.06 Version 1.4.0 + +- remove usage of innerHTML +- improved handling of textinput for IME and mobile +- add support for relative line numbers +- improve autocompletion popup + + 2018.03.26 Version 1.3.3 + +- fix regession in static-highlight extension +- use css animation for cursor blinking + + 2018.03.21 Version 1.3.2 + +- add experimental support for using ace-builds with webpack + + 2018.02.11 Version 1.3.1 + +- fixed regression with selectionChange event not firing some times +- improved handling of non-ascii characters in vim normal mode + + 2018.01.31 Version 1.3.0 + +- added copy copyWithEmptySelection option +- improved undoManager +- improved settings_menu plugin +- improved handling of files with very long lines +- fixed bug with scrolling editor out of view in transformed elements + + 2017.10.17 Version 1.2.9 + +- added support for bidirectional text, with monospace font (Alex Shensis) +- added support for emoji 😊 + +- new language modes + + - Red (Toomas Vooglaid) + - CSound (Nathan Whetsell) + - JSSM (John Haugeland) + +- New Themes + + - Dracula (Austin Schwartz) + + 2017.07.02 Version 1.2.8 + +- Fixed small bugs in searchbox and autocompleter + + 2017.06.18 Version 1.2.7 + +- Added Support for arrow keys on external IPad keyboard (Emanuele Tamponi) +- added match counter to searchbox extension + +* implemented higlighting of multiline strings in yaml mode (Maxim Trushin) +* improved haml syntax highlighter (Andrés Álvarez) + + 2016.12.03 Version 1.2.6 + +- Fixed IME handling on new Chrome +- Support for php 7 in the syntax checker + + 2016.08.16 Version 1.2.5 + +- Fixed regression in noconflict mode + + 2016.07.27 Version 1.2.4 + +- Maintenance release with several new modes and small bugfixes + + 2016.01.17 Version 1.2.3 + +- Bugfixes + - fix memory leak in setSession (Tyler Stalder) + - double click not working on linux/mac +- new language modes + + - reStructuredText (Robin Jarry) + - NSIS (Jan T. Sott) + + 2015.10.28 Version 1.2.1 + +- new language modes + + - Swift + - JSX + + 2015.07.11 Version 1.2.0 + +- New Features + + - Indented soft wrap (danyaPostfactum) + - Rounded borders on selections + +- API Changes + + - unified delta types `{start, end, action, lines}` (Alden Daniels https://github.com/ajaxorg/ace/pull/1745) + - "change" event listeners on session and editor get delta objects directly + +- new language modes + + - SQLServer (Morgan Yarbrough) + + 2015.04.03 Version 1.1.9 + + - Small Enhancements and Bugfixes + + 2014.11.08 Version 1.1.8 + +- API Changes + - `editor.commands.commandKeyBinding` now contains direct map from keys to commands instead of grouping them by hashid +- New Features + - Improved autoindent for html and php modes (Adam Jimenez) + - Find All from searchbox (Colton Voege) +- new language modes + + - Elixir, Elm + 2014.09.21 Version 1.1.7 + +- Bugfixes + + - fix several bugs in autocompletion + - workaround for inaccurate getBoundingClientRect on chrome 37 + + 2014.08.17 Version 1.1.6 + +- Bugfixes + - fix regression in double tap to highlight + - Improved Latex Mode (Daniel Felder) +- API Changes + + - editor.destroy destroys editor.session too (call editor.setSession(null) to prevent that) + +- new language modes + +* Praat (José Joaquín Atria) +* Eiffel (Victorien Elvinger) +* G-code (Adam Joseph Cook) + 2014.07.09 Version 1.1.5 + +- Bugfixes + + - fix regression in autocomplete popup + +- new language modes + +* gitignore (Devon Carew) + 2014.07.01 Version 1.1.4 + +- New Features + + - Highlight matching tags (Adam Jimenez) + - Improved jump to matching command (Adam Jimenez) + +- new language modes + +* AppleScript (Yaogang Lian) +* Vala + + 2014.03.08 Version 1.1.3 + +- New Features + + - Allow syntax checkers to be loaded from CDN (Derk-Jan Hartman) + - Add ColdFusion behavior (Abram Adams) + - add showLineNumbers option + - Add html syntax checker (danyaPostfactum) + +- new language modes + + - Gherkin (Patrick Nevels) + - Smarty + + 2013.12.02 Version 1.1.2 + +- New Features + - Accessibility Theme for Ace (Peter Xiao) + - use snipetManager for expanding emmet snippets + - update jshint to 2.1.4 + - improve php syntax checker (jdalegonzalez) + - add option for autoresizing + - add option for autohiding vertical scrollbar + - improvements to highlighting of xml like languages (danyaPostfactum) + - add support for autocompletion and snippets (gjtorikyan danyaPostfactum and others) + - add option to merge similar changes in undo history + - add scrollPastEnd option + - use html5 dragndrop for text dragging (danyaPostfactum) +- API Changes + + - fixed typo in HashHandler commmandManager + +- new language modes + + - Nix (Zef Hemel) + - Protobuf (Zef Hemel) + - Soy + - Handlebars + + 2013.06.04 Version 1.1.1 + + - Improved emacs keybindings (Robert Krahn) + - Added markClean, isClean methods to UndoManager (Joonsoo Jeon) + - Do not allow `Toggle comments` command to remove spaces from indentation + - Softer colors for indent guides in dark themes + +- new language modes + + - Ada + - Assembly_x86 + - Cobol + - D + - ejs + - MATLAB + - MySQL + - Twig + - Verilog + + 2013.05.01, Version 1.1.0 + +- API Changes + + - Default position of the editor container is changed to relative. Add `.ace_editor {position: absolute}` css rule to restore old behavior + - Changed default line-height to `normal` to not conflict with bootstrap. Use `line-height: inherit` for old behavior. + - Changed marker types accepted by session.addMarker. It now accepts "text"|"line"|"fullLine"|"screenLine" + - Internal classnames used by editor were made more consistent + - Introduced `editor.setOption/getOption/setOptions/getOptions` methods + - Introduced positionToIndex, indexToPosition methods + +- New Features + + - Improved emacs mode (chetstone) + with Incremental search and Occur modes (Robert Krahn) + + - Improved ime handling + - Searchbox (Vlad Zinculescu) + + - Added elastic tabstops lite extension (Garen Torikian) + - Added extension for whitespace manipulation + - Added extension for enabling spellchecking from contextmenu + - Added extension for displaying available keyboard shortcuts (Matthew Christopher Kastor-Inare III) + - Added extension for displaying options panel (Matthew Christopher Kastor-Inare III) + - Added modelist extension (Matthew Christopher Kastor-Inare III) + + - Improved toggleCommentLines and added ToggleCommentBlock command + - `:;` pairing in CSS mode (danyaPostfactum) + + - Added suppoert for Delete and SelectAll from context menu (danyaPostfactum) + + - Make wrapping behavior optional + - Selective bracket insertion/skipping + - Added commands for increase/decrease numbers, sort lines (Vlad Zinculescu) + - Folding for Markdown, Lua, LaTeX + - Selective bracket insertion/skipping for C-like languages + +- Many new languages + + - Scheme (Mu Lei) + - Dot (edwardsp) + - FreeMarker (nguillaumin) + - Tiny Mushcode (h3rb) + - Velocity (Ryan Griffith) + - TOML (Garen Torikian) + - LSL (Nemurimasu Neiro, Builders Brewery) + - Curly (Libo Cannici) + - vbScript (Jan Jongboom) + - R (RStudio) + - ABAP + - Lucene (Graham Scott) + - Haml (Garen Torikian) + - Objective-C (Garen Torikian) + - Makefile (Garen Torikian) + - TypeScript (Garen Torikian) + - Lisp (Garen Torikian) + - Stylus (Garen Torikian) + - Dart (Garen Torikian) + +- Live syntax checks + + - PHP (danyaPostfactum) + - Lua + +- New Themes + + - Chaos + - Terminal + 2012.09.17, Version 1.0.0 + +- New Features + + - Multiple cursors and selections (https://c9.io/site/blog/2012/08/be-an-armenian-warrior-with-block-selection-on-steroids/) + - Fold buttons displayed in the gutter + - Indent Guides + - Completely reworked vim mode (Sergi Mansilla) + - Improved emacs keybindings + - Autoclosing of html tags (danyaPostfactum) + +- 20 New language modes + + - Coldfusion (Russ) + - Diff + - GLSL (Ed Mackey) + - Go (Davide Saurino) + - Haxe (Jason O'Neil) + - Jade (Garen Torikian) + - jsx (Syu Kato) + - LaTeX (James Allen) + - Less (John Roepke) + - Liquid (Bernie Telles) + - Lua (Lee Gao) + - LuaPage (Choonster) + - Markdown (Chris Spencer) + - PostgreSQL (John DeSoi) + - Powershell (John Kane) + - Sh (Richo Healey) + - SQL (Jonathan Camile) + - Tcl (Cristoph Hochreiner) + - XQuery (William Candillion) + - Yaml (Meg Sharkey) + + * Live syntax checks + + - for XQuery and JSON + +- New Themes + + - Ambiance (Irakli Gozalishvili) + - Dreamweaver (Adam Jimenez) + - Github (bootstraponline) + - Tommorrow themes (https://github.com/chriskempson/tomorrow-theme) + - XCode + +- Many Small Enhancements and Bugfixes + + 2011.08.02, Version 0.2.0 + +- Split view (Julian Viereck) + + - split editor area horizontally or vertivally to show two files at the same + time + +- Code Folding (Julian Viereck) + + - Unstructured code folding + - Will be the basis for language aware folding + +- Mode behaviours (Chris Spencer) + + - Adds mode specific hooks which allow transformations of entered text + - Autoclosing of braces, paranthesis and quotation marks in C style modes + - Autoclosing of angular brackets in XML style modes + +- New language modes + - Clojure (Carin Meier) + - C# (Rob Conery) + - Groovy (Ben Tilford) + - Scala (Ben Tilford) + - JSON + - OCaml (Sergi Mansilla) + - Perl (Panagiotis Astithas) + - SCSS/SASS (Andreas Madsen) + - SVG + - Textile (Kelley van Evert) + - SCAD (Jacob Hansson) +- Live syntax checks + + - Lint for CSS using CSS Lint + - CoffeeScript + +- New Themes + + - Crimson Editor (iebuggy) + - Merbivore (Michael Schwartz) + - Merbivore soft (Michael Schwartz) + - Solarized dark/light (David Alan Hjelle) + - Vibrant Ink (Michael Schwartz) + +- Small Features/Enhancements + + - Lots of render performance optimizations (Harutyun Amirjanyan) + - Improved Ruby highlighting (Chris Wanstrath, Trent Ogren) + - Improved PHP highlighting (Thomas Hruska) + - Improved CSS highlighting (Sean Kellogg) + - Clicks which cause the editor to be focused don't reset the selection + - Make padding text layer specific so that print margin and active line + highlight are not affected (Irakli Gozalishvili) + - Added setFontSize method + - Improved vi keybindings (Trent Ogren) + - When unfocused make cursor transparent instead of removing it (Harutyun Amirjanyan) + - Support for matching groups in tokenizer with arrays of tokens (Chris Spencer) + +- Bug fixes + + - Add support for the new OSX scroll bars + - Properly highlight JavaScript regexp literals + - Proper handling of unicode characters in JavaScript identifiers + - Fix remove lines command on last line (Harutyun Amirjanyan) + - Fix scroll wheel sluggishness in Safari + - Make keyboard infrastructure route keys like []^$ the right way (Julian Viereck) + + 2011.02.14, Version 0.1.6 + +- Floating Anchors + - An Anchor is a floating pointer in the document. + - Whenever text is inserted or deleted before the cursor, the position of + the cursor is updated + - Usesd for the cursor and selection + - Basis for bookmarks, multiple cursors and snippets in the future +- Extensive support for Cocoa style keybindings on the Mac +- New commands: + - center selection in viewport + - remove to end/start of line + - split line + - transpose letters +- Refator markers + - Custom code can be used to render markers + - Markers can be in front or behind the text + - Markers are now stored in the session (was in the renderer) +- Lots of IE8 fixes including copy, cut and selections +- Unit tests can also be run in the browser + +- Soft wrap can adapt to the width of the editor (Mike Ratcliffe, Joe Cheng) +- Add minimal node server server.js to run the Ace demo in Chrome +- The top level editor.html demo has been renamed to index.html +- Bug fixes + + - Fixed gotoLine to consider wrapped lines when calculating where to scroll to (James Allen) + - Fixed isues when the editor was scrolled in the web page (Eric Allam) + - Highlighting of Python string literals + - Syntax rule for PHP comments + + 2011.02.08, Version 0.1.5 + +- Add Coffeescript Mode (Satoshi Murakami) +- Fix word wrap bug (Julian Viereck) +- Fix packaged version of the Eclipse mode +- Loading of workers is more robust +- Fix "click selection" +- Allow tokizing empty lines (Daniel Krech) +- Make PageUp/Down behavior more consistent with native OS (Joe Cheng) + + 2011.02.04, Version 0.1.4 + +- Add C/C++ mode contributed by Gastón Kleiman +- Fix exception in key input + + 2011.02.04, Version 0.1.3 + +- Let the packaged version play nice with requireJS +- Add Ruby mode contributed by Shlomo Zalman Heigh +- Add Java mode contributed by Tom Tasche +- Fix annotation bug +- Changing a document added a new empty line at the end diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..3b64466870c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,4 @@ +## Code of Conduct +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +opensource-codeofconduct@amazon.com with any additional questions or comments. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 062af59c3df..d2d4e8c2ec6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,13 +3,6 @@ Contributing Ace 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! -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: - -1. [The Individual CLA](https://docs.google.com/a/c9.io/forms/d/1MfmfrxqD_PNlNsuK0lC2KSelRLxGLGfh_wEcG0ijVvo/viewform): use this version if you're working on the Cloud9 SDK or open source projects in your spare time, or can clearly claim ownership of copyright in what you'll be submitting. -2. [The Corporate CLA](https://docs.google.com/a/c9.io/forms/d/1vFejn4111GdnCNuQ6BfnJDaxdsUEMD4KCo1ayovAfu0/viewform): have your corporate lawyer review and submit this if your company is going to be contributing to the Cloud9 SDK and/or open source projects. - -If you want to contribute to the Cloud9 SDK and/or open source projects please go to the online form, fill it out and submit it. +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. Do make sure that your changes are covered by test cases to pass the pull request checks which exists inorder to keep ace robust. Happy coding, Cloud9 diff --git a/ChangeLog.txt b/ChangeLog.txt deleted file mode 100644 index 5c491daa7e5..00000000000 --- a/ChangeLog.txt +++ /dev/null @@ -1,416 +0,0 @@ -2018.03.26 Version 1.3.3 -* fix regession in static-highlight extension -* use css animation for cursor blinking - -2018.03.21 Version 1.3.2 -* add experimental support for using ace-builds with webpack - -2018.02.11 Version 1.3.1 - -* fixed regression with selectionChange event not firing some times -* improved handling of non-ascii characters in vim normal mode - -2018.01.31 Version 1.3.0 - -* added copy copyWithEmptySelection option -* improved undoManager -* improved settings_menu plugin -* improved handling of files with very long lines -* fixed bug with scrolling editor out of view in transformed elements - -2017.10.17 Version 1.2.9 - -* added support for bidirectional text, with monospace font (Alex Shensis) -* added support for emoji 😊 - -* new language modes - - Red (Toomas Vooglaid) - - CSound (Nathan Whetsell) - - JSSM (John Haugeland) - -* New Themes - - Dracula (Austin Schwartz) - -2017.07.02 Version 1.2.8 -* Fixed small bugs in searchbox and autocompleter - -2017.06.18 Version 1.2.7 - -* Added Support for arrow keys on external IPad keyboard (Emanuele Tamponi) -* added match counter to searchbox extension - -- implemented higlighting of multiline strings in yaml mode (Maxim Trushin) -- improved haml syntax highlighter (Andrés Álvarez) - -2016.12.03 Version 1.2.6 - -* Fixed IME handling on new Chrome -* Support for php 7 in the syntax checker - -2016.08.16 Version 1.2.5 - -* Fixed regression in noconflict mode - -2016.07.27 Version 1.2.4 - -* Maintenance release with several new modes and small bugfixes - -2016.01.17 Version 1.2.3 - -* Bugfixes - - fix memory leak in setSession (Tyler Stalder) - - double click not working on linux/mac - -* new language modes - - reStructuredText (Robin Jarry) - - NSIS (Jan T. Sott) - - -2015.10.28 Version 1.2.1 - -* new language modes - - Swift - - JSX - -2015.07.11 Version 1.2.0 - -* New Features - - Indented soft wrap (danyaPostfactum) - - Rounded borders on selections - -* API Changes - - unified delta types `{start, end, action, lines}` (Alden Daniels https://github.com/ajaxorg/ace/pull/1745) - - "change" event listeners on session and editor get delta objects directly - -* new language modes - - SQLServer (Morgan Yarbrough) - -2015.04.03 Version 1.1.9 - - - Small Enhancements and Bugfixes - -2014.11.08 Version 1.1.8 - -* API Changes - - `editor.commands.commandKeyBinding` now contains direct map from keys to commands instead of grouping them by hashid - -* New Features - - Improved autoindent for html and php modes (Adam Jimenez) - - Find All from searchbox (Colton Voege) - -* new language modes - - Elixir, Elm - -2014.09.21 Version 1.1.7 - -* Bugfixes - - fix several bugs in autocompletion - - workaround for inaccurate getBoundingClientRect on chrome 37 - -2014.08.17 Version 1.1.6 - -* Bugfixes - - fix regression in double tap to highlight - - Improved Latex Mode (Daniel Felder) - -* API Changes - - editor.destroy destroys editor.session too (call editor.setSession(null) to prevent that) - -* new language modes - - Praat (José Joaquín Atria) - - Eiffel (Victorien Elvinger) - - G-code (Adam Joseph Cook) - -2014.07.09 Version 1.1.5 - -* Bugfixes - - fix regression in autocomplete popup - -* new language modes - - gitignore (Devon Carew) - -2014.07.01 Version 1.1.4 - -* New Features - - Highlight matching tags (Adam Jimenez) - - Improved jump to matching command (Adam Jimenez) - -* new language modes - - AppleScript (Yaogang Lian) - - Vala - -2014.03.08 Version 1.1.3 - -* New Features - - Allow syntax checkers to be loaded from CDN (Derk-Jan Hartman) - - Add ColdFusion behavior (Abram Adams) - - add showLineNumbers option - - Add html syntax checker (danyaPostfactum) - -* new language modes - - Gherkin (Patrick Nevels) - - Smarty - -2013.12.02 Version 1.1.2 - -* New Features - - Accessibility Theme for Ace (Peter Xiao) - - use snipetManager for expanding emmet snippets - - update jshint to 2.1.4 - - improve php syntax checker (jdalegonzalez) - - add option for autoresizing - - add option for autohiding vertical scrollbar - - improvements to highlighting of xml like languages (danyaPostfactum) - - add support for autocompletion and snippets (gjtorikyan danyaPostfactum and others) - - add option to merge similar changes in undo history - - add scrollPastEnd option - - use html5 dragndrop for text dragging (danyaPostfactum) - -* API Changes - - fixed typo in HashHandler commmandManager - -* new language modes - - Nix (Zef Hemel) - - Protobuf (Zef Hemel) - - Soy - - Handlebars - -2013.06.04 Version 1.1.1 - - - Improved emacs keybindings (Robert Krahn) - - Added markClean, isClean methods to UndoManager (Joonsoo Jeon) - - Do not allow `Toggle comments` command to remove spaces from indentation - - Softer colors for indent guides in dark themes - -* new language modes - - Ada - - Assembly_x86 - - Cobol - - D - - ejs - - MATLAB - - MySQL - - Twig - - Verilog - -2013.05.01, Version 1.1.0 - -* API Changes - - Default position of the editor container is changed to relative. Add `.ace_editor {position: absolute}` css rule to restore old behavior - - Changed default line-height to `normal` to not conflict with bootstrap. Use `line-height: inherit` for old behavior. - - Changed marker types accepted by session.addMarker. It now accepts "text"|"line"|"fullLine"|"screenLine" - - Internal classnames used by editor were made more consistent - - Introduced `editor.setOption/getOption/setOptions/getOptions` methods - - Introduced positionToIndex, indexToPosition methods - -* New Features - - Improved emacs mode (chetstone) - with Incremental search and Occur modes (Robert Krahn) - - - Improved ime handling - - Searchbox (Vlad Zinculescu) - - - Added elastic tabstops lite extension (Garen Torikian) - - Added extension for whitespace manipulation - - Added extension for enabling spellchecking from contextmenu - - Added extension for displaying available keyboard shortcuts (Matthew Christopher Kastor-Inare III) - - Added extension for displaying options panel (Matthew Christopher Kastor-Inare III) - - Added modelist extension (Matthew Christopher Kastor-Inare III) - - - Improved toggleCommentLines and added ToggleCommentBlock command - - `:;` pairing in CSS mode (danyaPostfactum) - - - Added suppoert for Delete and SelectAll from context menu (danyaPostfactum) - - - Make wrapping behavior optional - - Selective bracket insertion/skipping - - - Added commands for increase/decrease numbers, sort lines (Vlad Zinculescu) - - Folding for Markdown, Lua, LaTeX - - Selective bracket insertion/skipping for C-like languages - -* Many new languages - - Scheme (Mu Lei) - - Dot (edwardsp) - - FreeMarker (nguillaumin) - - Tiny Mushcode (h3rb) - - Velocity (Ryan Griffith) - - TOML (Garen Torikian) - - LSL (Nemurimasu Neiro, Builders Brewery) - - Curly (Libo Cannici) - - vbScript (Jan Jongboom) - - R (RStudio) - - ABAP - - Lucene (Graham Scott) - - Haml (Garen Torikian) - - Objective-C (Garen Torikian) - - Makefile (Garen Torikian) - - TypeScript (Garen Torikian) - - Lisp (Garen Torikian) - - Stylus (Garen Torikian) - - Dart (Garen Torikian) - -* Live syntax checks - - PHP (danyaPostfactum) - - Lua - -* New Themes - - Chaos - - Terminal - -2012.09.17, Version 1.0.0 - -* New Features - - Multiple cursors and selections (https://c9.io/site/blog/2012/08/be-an-armenian-warrior-with-block-selection-on-steroids/) - - Fold buttons displayed in the gutter - - Indent Guides - - Completely reworked vim mode (Sergi Mansilla) - - Improved emacs keybindings - - Autoclosing of html tags (danyaPostfactum) - -* 20 New language modes - - Coldfusion (Russ) - - Diff - - GLSL (Ed Mackey) - - Go (Davide Saurino) - - Haxe (Jason O'Neil) - - Jade (Garen Torikian) - - jsx (Syu Kato) - - LaTeX (James Allen) - - Less (John Roepke) - - Liquid (Bernie Telles) - - Lua (Lee Gao) - - LuaPage (Choonster) - - Markdown (Chris Spencer) - - PostgreSQL (John DeSoi) - - Powershell (John Kane) - - Sh (Richo Healey) - - SQL (Jonathan Camile) - - Tcl (Cristoph Hochreiner) - - XQuery (William Candillion) - - Yaml (Meg Sharkey) - - * Live syntax checks - - for XQuery and JSON - -* New Themes - - Ambiance (Irakli Gozalishvili) - - Dreamweaver (Adam Jimenez) - - Github (bootstraponline) - - Tommorrow themes (https://github.com/chriskempson/tomorrow-theme) - - XCode - -* Many Small Enhancements and Bugfixes - -2011.08.02, Version 0.2.0 - -* Split view (Julian Viereck) - - split editor area horizontally or vertivally to show two files at the same - time - -* Code Folding (Julian Viereck) - - Unstructured code folding - - Will be the basis for language aware folding - -* Mode behaviours (Chris Spencer) - - Adds mode specific hooks which allow transformations of entered text - - Autoclosing of braces, paranthesis and quotation marks in C style modes - - Autoclosing of angular brackets in XML style modes - -* New language modes - - Clojure (Carin Meier) - - C# (Rob Conery) - - Groovy (Ben Tilford) - - Scala (Ben Tilford) - - JSON - - OCaml (Sergi Mansilla) - - Perl (Panagiotis Astithas) - - SCSS/SASS (Andreas Madsen) - - SVG - - Textile (Kelley van Evert) - - SCAD (Jacob Hansson) - -* Live syntax checks - - Lint for CSS using CSS Lint - - CoffeeScript - -* New Themes - - Crimson Editor (iebuggy) - - Merbivore (Michael Schwartz) - - Merbivore soft (Michael Schwartz) - - Solarized dark/light (David Alan Hjelle) - - Vibrant Ink (Michael Schwartz) - -* Small Features/Enhancements - - Lots of render performance optimizations (Harutyun Amirjanyan) - - Improved Ruby highlighting (Chris Wanstrath, Trent Ogren) - - Improved PHP highlighting (Thomas Hruska) - - Improved CSS highlighting (Sean Kellogg) - - Clicks which cause the editor to be focused don't reset the selection - - Make padding text layer specific so that print margin and active line - highlight are not affected (Irakli Gozalishvili) - - Added setFontSize method - - Improved vi keybindings (Trent Ogren) - - When unfocused make cursor transparent instead of removing it (Harutyun Amirjanyan) - - Support for matching groups in tokenizer with arrays of tokens (Chris Spencer) - -* Bug fixes - - Add support for the new OSX scroll bars - - Properly highlight JavaScript regexp literals - - Proper handling of unicode characters in JavaScript identifiers - - Fix remove lines command on last line (Harutyun Amirjanyan) - - Fix scroll wheel sluggishness in Safari - - Make keyboard infrastructure route keys like []^$ the right way (Julian Viereck) - -2011.02.14, Version 0.1.6 - -* Floating Anchors - - An Anchor is a floating pointer in the document. - - Whenever text is inserted or deleted before the cursor, the position of - the cursor is updated - - Usesd for the cursor and selection - - Basis for bookmarks, multiple cursors and snippets in the future -* Extensive support for Cocoa style keybindings on the Mac -* New commands: - - center selection in viewport - - remove to end/start of line - - split line - - transpose letters -* Refator markers - - Custom code can be used to render markers - - Markers can be in front or behind the text - - Markers are now stored in the session (was in the renderer) -* Lots of IE8 fixes including copy, cut and selections -* Unit tests can also be run in the browser - -* Soft wrap can adapt to the width of the editor (Mike Ratcliffe, Joe Cheng) -* Add minimal node server server.js to run the Ace demo in Chrome -* The top level editor.html demo has been renamed to index.html -* Bug fixes - - Fixed gotoLine to consider wrapped lines when calculating where to scroll to (James Allen) - - Fixed isues when the editor was scrolled in the web page (Eric Allam) - - Highlighting of Python string literals - - Syntax rule for PHP comments - -2011.02.08, Version 0.1.5 - -* Add Coffeescript Mode (Satoshi Murakami) -* Fix word wrap bug (Julian Viereck) -* Fix packaged version of the Eclipse mode -* Loading of workers is more robust -* Fix "click selection" -* Allow tokizing empty lines (Daniel Krech) -* Make PageUp/Down behavior more consistent with native OS (Joe Cheng) - -2011.02.04, Version 0.1.4 - -* Add C/C++ mode contributed by Gastón Kleiman -* Fix exception in key input - -2011.02.04, Version 0.1.3 - -* Let the packaged version play nice with requireJS -* Add Ruby mode contributed by Shlomo Zalman Heigh -* Add Java mode contributed by Tom Tasche -* Fix annotation bug -* Changing a document added a new empty line at the end diff --git a/Makefile.dryice.js b/Makefile.dryice.js index 2556766137e..3dbaa3de616 100755 --- a/Makefile.dryice.js +++ b/Makefile.dryice.js @@ -29,19 +29,72 @@ * * ***** END LICENSE BLOCK ***** */ +/*global Buffer, setImmediate*/ + var fs = require("fs"); var path = require("path"); var copy = require('architect-build/copy'); var build = require('architect-build/build'); +var { + updateDeclarationModuleNames, + generateDeclaration, + SEPARATE_MODULES +} = require('./tool/ace_declaration_generator'); var ACE_HOME = __dirname; var BUILD_DIR = ACE_HOME + "/build"; var CACHE = {}; +function generateAmdModules() { + var root = ACE_HOME + "/"; + function iterate(dir) { + var filenames = fs.readdirSync(root + dir); + filenames.forEach(function(name) { + var path = dir + name; + var stat = fs.statSync(root + path); + var newPath = path.replace("src", "lib/ace"); + if (stat.isDirectory()) { + try { + fs.mkdirSync(root + newPath); + } catch(e) {} + iterate(path + "/"); + } else if (/\.js/.test(name) && !/worker_client\.js$/.test(name)) { + transform(path, newPath); + } + }); + } + function transform(path, newPath) { + var data = fs.readFileSync(root + path, "utf-8"); + data = "define(function(require, exports, module){" + + compileTypescript(data) + +"\n});"; + fs.writeFileSync(root + newPath, data, "utf-8"); + } + function compileTypescript(code) { + var ts = require("typescript"); + return ts.transpileModule(code, { + compilerOptions: { + newLine: "lf", + downlevelIteration: true, + suppressExcessPropertyErrors: true, + module: ts.ModuleKind.CommonJS, + removeComments: false, + sourceMap: false, + inlineSourceMap: false, + target: "ES5" + }, + fileName: "" + }).outputText; + } + + iterate("src/"); +} + function main(args) { if (args.indexOf("updateModes") !== -1) { return updateModes(); } + var type = "minimal"; args = args.map(function(x) { if (x[0] == "-" && x[1] != "-") @@ -59,6 +112,19 @@ function main(args) { if (args.indexOf("--h") != -1 || args.indexOf("-h") != -1 || args.indexOf("--help") != -1) { return showHelp(); } + + if (type == "css") { + return extractCss(); + } + if (type == "nls") { + return extractNls(); + } + + if (args.indexOf("--reuse") === -1) { + console.log("updating files in lib/ace"); + generateAmdModules(); + } + if (type == "minimal") { buildAce({ compress: args.indexOf("--m") != -1, @@ -86,6 +152,8 @@ function showHelp(type) { console.log(" demo Runs demo build of Ace"); console.log(" full all of above"); console.log(" highlighter "); + console.log(" css extract css files"); + console.log(" nls extract nls messages"); console.log("args:"); console.log(" --target ./path path to build folder"); console.log("flags:"); @@ -103,7 +171,7 @@ function ace() { copy.file(ACE_HOME + "/build_support/editor.html", BUILD_DIR + "/editor.html"); copy.file(ACE_HOME + "/LICENSE", BUILD_DIR + "/LICENSE"); - copy.file(ACE_HOME + "/ChangeLog.txt", BUILD_DIR + "/ChangeLog.txt"); + copy.file(ACE_HOME + "/CHANGELOG.md", BUILD_DIR + "/CHANGELOG.md"); console.log('# ace ---------'); for (var i = 0; i < 4; i++) { @@ -111,32 +179,76 @@ function ace() { } } -function buildTypes() { - copy.file(ACE_HOME + "/ace.d.ts", BUILD_DIR + "/ace.d.ts"); +function correctDeclarationsForBuild(path, additionalDeclarations) { + var definitions = fs.readFileSync(path, 'utf8'); + var newDefinitions = updateDeclarationModuleNames(definitions); + if (additionalDeclarations) { + newDefinitions = newDefinitions + '\n' + additionalDeclarations; + } + if (/ace\.d\.ts$/.test(path)) { + var aceRequire = "$1\n export function require(name: string): any;"; + newDefinitions = newDefinitions.replace(/(declare\smodule\s"ace\-builds"\s{)/, aceRequire); + } + fs.writeFileSync(path, newDefinitions); +} +function buildTypes() { + // ace-builds package has different structure and can't use mode types defined for the ace-code. var paths = fs.readdirSync(BUILD_DIR + '/src-noconflict'); - var pathModules = paths.map(function(path) { - if (/^(mode|theme|ext|keybinding)-/.test(path)) { + var typeDir = BUILD_DIR + "/types"; + + if (!fs.existsSync(typeDir)) { + fs.mkdirSync(typeDir); + } + + fs.readdirSync(BUILD_DIR + '/src-noconflict/snippets').forEach(function(path) { + paths.push("snippets/" + path); + }); + + var moduleNameRegex = /^(keybinding)-/; + + var pathModules = [ + "declare module 'ace-builds/webpack-resolver';", + "declare module 'ace-builds/esm-resolver';", + "declare module 'ace-builds/src-noconflict/ace';" + ].concat(paths.map(function(path) { + if (moduleNameRegex.test(path)) { var moduleName = path.split('.')[0]; return "declare module 'ace-builds/src-noconflict/" + moduleName + "';"; } - }).filter(Boolean).join('\n') - + "\ndeclare module 'ace-builds/webpack-resolver';\n"; - - fs.appendFileSync(BUILD_DIR + '/ace.d.ts', '\n' + pathModules); + }).filter(Boolean)).join("\n") + "\n"; + fs.copyFileSync(ACE_HOME + '/ace-internal.d.ts', BUILD_DIR + '/ace.d.ts'); + generateDeclaration(BUILD_DIR + '/ace.d.ts'); + fs.copyFileSync(ACE_HOME + '/ace-modes.d.ts', BUILD_DIR + '/ace-modes.d.ts'); + correctDeclarationsForBuild(BUILD_DIR + '/ace.d.ts', pathModules); + correctDeclarationsForBuild(BUILD_DIR + '/ace-modes.d.ts'); + + let allModules = SEPARATE_MODULES; + allModules.push("modules"); // core modules + allModules.forEach(function (key) { + let fileName = '/ace-' + key + '.d.ts'; + fs.copyFileSync(ACE_HOME + '/types' + fileName, BUILD_DIR + '/types' + fileName); + correctDeclarationsForBuild(BUILD_DIR + '/types' + fileName); + }); + + var esmUrls = []; + var loader = paths.map(function(path) { if (/\.js$/.test(path) && !/^ace\.js$/.test(path)) { var moduleName = path.split('.')[0].replace(/-/, "/"); if (/^worker/.test(moduleName)) moduleName = "mode" + moduleName.slice(6) + "_worker"; moduleName = moduleName.replace(/keybinding/, "keyboard"); - return "ace.config.setModuleUrl('ace/" + moduleName + "', require('file-loader!./src-noconflict/" + path + "'))"; + esmUrls.push("ace.config.setModuleLoader('ace/" + moduleName + "', () => import('./src-noconflict/" + path + "'));"); + return "ace.config.setModuleUrl('ace/" + moduleName + "', require('file-loader?esModule=false!./src-noconflict/" + path + "'));"; } }).join('\n'); - + var esmLoader = esmUrls.join('\n'); + fs.writeFileSync(BUILD_DIR + '/webpack-resolver.js', loader, "utf8"); + fs.writeFileSync(BUILD_DIR + '/esm-resolver.js', esmLoader, "utf8"); } function demo() { @@ -160,6 +272,7 @@ function demo() { ); } + require("rimraf").sync(BUILD_DIR + "/demo/kitchen-sink/docs/"); copy(ACE_HOME +"/demo/kitchen-sink/docs/", BUILD_DIR + "/demo/kitchen-sink/docs/"); copy.file(ACE_HOME + "/demo/kitchen-sink/logo.png", BUILD_DIR + "/demo/kitchen-sink/logo.png"); @@ -183,8 +296,8 @@ function demo() { removeRequireJS = true; var scripts = m.split(/,\s*/); var result = []; - function comment(str) {result.push("")} - function script(str) {result.push('')} + function comment(str) {result.push("");} + function script(str) {result.push('');} scripts.forEach(function(s) { s = s.replace(/"/g, ""); if (s == "ace/ace") { @@ -199,10 +312,12 @@ function demo() { result.push(" ``` +*Exploring configuration options [Configuring-Ace](https://github.com/ajaxorg/ace/wiki/Configuring-Ace/)* With "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. @@ -98,11 +100,11 @@ Documentation Additional usage information, including events to listen to and extending syntax highlighters, can be found [on the main Ace website](http://ace.c9.io). -You can also find API documentation at [http://ace.c9.io/#nav=api](http://ace.c9.io/#nav=api). +You can also find API documentation at [https://ajaxorg.github.io/ace-api-docs/](https://ajaxorg.github.io/ace-api-docs/). Also check out the sample code for the kitchen sink [demo app](https://github.com/ajaxorg/ace/blob/master/demo/kitchen-sink/demo.js). -If you still need help, feel free to drop a mail on the [ace mailing list](http://groups.google.com/group/ace-discuss), or at `irc.freenode.net#ace`. +If you still need help, feel free to ask a question on our [discussions page](https://github.com/ajaxorg/ace/discussions). Running Ace ----------- @@ -146,14 +148,14 @@ Running the Unit Tests The Ace unit tests can run on node.js. Assuming you have already done `npm install`, just call: ```bash -node lib/ace/test/all.js +npm run test ``` You can also run the tests in your browser by serving: - http://localhost:8888/lib/ace/test/tests.html + http://localhost:8888/src/test/tests.html -This makes debugging failing tests way more easier. +This makes debugging failing tests much easier. Contributing ----------------------------- diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000000..18d15a930cf --- /dev/null +++ b/_config.yml @@ -0,0 +1,5 @@ +# Config file for Jekyll, which is used by GH pages to build the Ace website. +# Some files in the docs folder can cause Jekyll to trip up so we ignore those. +# https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/about-github-pages-and-jekyll +exclude: + - "demo/kitchen-sink/docs" \ No newline at end of file diff --git a/ace-internal.d.ts b/ace-internal.d.ts new file mode 100644 index 00000000000..926b3b4a959 --- /dev/null +++ b/ace-internal.d.ts @@ -0,0 +1,1668 @@ +export namespace Ace { + type Anchor = import("./src/anchor").Anchor; + type Editor = import("./src/editor").Editor; + type EditSession = import("./src/edit_session").EditSession; + type Document = import("./src/document").Document; + type Fold = import("./src/edit_session/fold").Fold; + type FoldLine = import("./src/edit_session/fold_line").FoldLine; + type Range = import("./src/range").Range; + type VirtualRenderer = import("./src/virtual_renderer").VirtualRenderer; + type UndoManager = import("./src/undomanager").UndoManager; + type Tokenizer = import("./src/tokenizer").Tokenizer; + type TokenIterator = import("./src/token_iterator").TokenIterator; + type Selection = import("./src/selection").Selection; + type Autocomplete = import("./src/autocomplete").Autocomplete; + type InlineAutocomplete = import("./src/ext/inline_autocomplete").InlineAutocomplete; + type CompletionProvider = import("./src/autocomplete").CompletionProvider; + type AcePopup = import("./src/autocomplete/popup").AcePopup; + type AceInline = import("./src/autocomplete/inline").AceInline; + type MouseEvent = import("./src/mouse/mouse_event").MouseEvent; + type RangeList = import("./src/range_list").RangeList; + type FilteredList = import("./src/autocomplete").FilteredList; + type LineWidgets = import("./src/line_widgets").LineWidgets; + type SearchBox = import("./src/ext/searchbox").SearchBox; + type Occur = import("./src/occur").Occur; + type DefaultHandlers = import("./src/mouse/default_handlers").DefaultHandlers; + type GutterHandler = import("./src/mouse/default_gutter_handler").GutterHandler; + type DragdropHandler = import("./src/mouse/dragdrop_handler").DragdropHandler; + type AppConfig = import("./src/lib/app_config").AppConfig; + type Config = typeof import("./src/config"); + type GutterTooltip = import( "./src/mouse/default_gutter_handler").GutterTooltip; + type GutterKeyboardEvent = import( "./src/keyboard/gutter_handler").GutterKeyboardEvent; + type HoverTooltip = import("./src/tooltip").HoverTooltip; + type Tooltip = import("./src/tooltip").Tooltip; + type TextInput = import("./src/keyboard/textinput").TextInput; + type DiffChunk = import("./src/ext/diff/base_diff_view").DiffChunk; + + type AfterLoadCallback = (err: Error | null, module: unknown) => void; + type LoaderFunction = (moduleName: string, afterLoad: AfterLoadCallback) => void; + + export interface ConfigOptions { + packaged: boolean, + workerPath: string | null, + modePath: string | null, + themePath: string | null, + basePath: string, + suffix: string, + $moduleUrls: { [url: string]: string }, + loadWorkerFromBlob: boolean, + sharedPopups: boolean, + useStrictCSP: boolean | null + } + + interface Theme { + cssClass?: string; + cssText?: string; + $id?: string; + padding?: number | string; + isDark?: boolean; + } + + interface ScrollBar { + setVisible(visible: boolean): void; + + [key: string]: any; + } + + interface HScrollbar extends ScrollBar { + setWidth(width: number): void; + } + + interface VScrollbar extends ScrollBar { + setHeight(width: number): void; + } + + interface LayerConfig { + width: number, + padding: number, + firstRow: number, + firstRowScreen: number, + lastRow: number, + lineHeight: number, + characterWidth: number, + minHeight: number, + maxHeight: number, + offset: number, + height: number, + gutterOffset: number + } + + interface HardWrapOptions { + /** First row of the range to process */ + startRow: number; + /** Last row of the range to process */ + endRow: number; + /** Whether to merge short adjacent lines that fit within the limit */ + allowMerge?: boolean; + /** Maximum column width for line wrapping (defaults to editor's print margin) */ + column?: number; + } + + interface CommandBarOptions { + maxElementsOnTooltip: number; + alwaysShow: boolean; + showDelay: number; + hideDelay: number; + } + + interface ScreenCoordinates { + row: number, + column: number, + side?: 1 | -1, + offsetX?: number + } + + interface Folding { + $foldData: FoldLine[]; + + /** + * Looks up a fold at a given row/column. Possible values for side: + * -1: ignore a fold if fold.start = row/column + * +1: ignore a fold if fold.end = row/column + **/ + getFoldAt(row: number, column: number, side?: number): Ace.Fold; + + /** + * Returns all folds in the given range. Note, that this will return folds + **/ + getFoldsInRange(range: Ace.Range | Ace.Delta): Ace.Fold[]; + + getFoldsInRangeList(ranges: Ace.Range[] | Ace.Range): Ace.Fold[]; + + /** + * Returns all folds in the document + */ + getAllFolds(): Ace.Fold[]; + + /** + * Returns the string between folds at the given position. + * E.g. + * foob|arwolrd -> "bar" + * foobarwol|rd -> "world" + * foobarwolrd -> + * + * where | means the position of row/column + * + * The trim option determs if the return string should be trimed according + * to the "side" passed with the trim value: + * + * E.g. + * foob|arwolrd -trim=-1> "b" + * foobarwol|rd -trim=+1> "rld" + * fo|obarwolrd -trim=00> "foo" + */ + getFoldStringAt(row: number, column: number, trim?: number, foldLine?: Ace.FoldLine): string | null; + + getFoldLine(docRow: number, startFoldLine?: Ace.FoldLine): null | Ace.FoldLine; + + /** + * Returns the fold which starts after or contains docRow + */ + getNextFoldLine(docRow: number, startFoldLine?: Ace.FoldLine): null | Ace.FoldLine; + + getFoldedRowCount(first: number, last: number): number; + + $addFoldLine(foldLine: FoldLine): Ace.FoldLine; + + /** + * Adds a new fold. + * @returns {Ace.Fold} + * The new created Fold object or an existing fold object in case the + * passed in range fits an existing fold exactly. + */ + addFold(placeholder: Ace.Fold | string, range?: Ace.Range): Ace.Fold; + + $modified: boolean; + + addFolds(folds: Ace.Fold[]): void; + + removeFold(fold: Ace.Fold): void; + + removeFolds(folds: Ace.Fold[]): void; + + expandFold(fold: Ace.Fold): void; + + expandFolds(folds: Ace.Fold[]): void; + + unfold(location?: number | null | Ace.Point | Ace.Range | Ace.Range[], expandInner?: boolean): Ace.Fold[] | undefined; + + /** + * Checks if a given documentRow is folded. This is true if there are some + * folded parts such that some parts of the line is still visible. + **/ + isRowFolded(docRow: number, startFoldRow?: Ace.FoldLine): boolean; + + getRowFoldEnd(docRow: number, startFoldRow?: Ace.FoldLine): number; + + getRowFoldStart(docRow: number, startFoldRow?: Ace.FoldLine): number; + + getFoldDisplayLine(foldLine: Ace.FoldLine, endRow?: number | null, endColumn?: number | null, startRow?: number | null, startColumn?: number | null): string; + + getDisplayLine(row: number, endColumn: number | null, startRow: number | null, startColumn: number | null): string; + + $cloneFoldData(): Ace.FoldLine[]; + + toggleFold(tryToUnfold?: boolean): void; + + getCommentFoldRange(row: number, column: number, dir?: number): Ace.Range | undefined; + + foldAll(startRow?: number | null, endRow?: number | null, depth?: number | null, test?: Function): void; + + foldToLevel(level: number): void; + + foldAllComments(): void; + + $foldStyles: { + manual: number; + markbegin: number; + markbeginend: number; + }; + $foldStyle: string; + + setFoldStyle(style: string): void; + + $setFolding(foldMode: Ace.FoldMode): void; + + $foldMode: any; + foldWidgets: any[]; + getFoldWidget: any; + getFoldWidgetRange: any; + $updateFoldWidgets: any; + $tokenizerUpdateFoldWidgets: any; + + getParentFoldRangeData(row: number, ignoreCurrent?: boolean): { + range?: Ace.Range; + firstRange?: Ace.Range; + }; + + onFoldWidgetClick(row: number, e: any): void; + + $toggleFoldWidget(row: number, options: any): Fold | any; + + /** + * + * @param {boolean} [toggleParent] + */ + toggleFoldWidget(toggleParent?: boolean): void; + + updateFoldWidgets(delta: Ace.Delta): void; + + tokenizerUpdateFoldWidgets(e: any): void; + } + + interface BracketMatch { + findMatchingBracket: (position: Point, chr?: string) => Point; + + getBracketRange: (pos: Point) => null | Range; + /** + * Returns: + * * null if there is no any bracket at `pos`; + * * two Ranges if there is opening and closing brackets; + * * one Range if there is only one bracket + */ + getMatchingBracketRanges: (pos: Point, isBackwards?: boolean) => null | Range[]; + $brackets: { + ")": string; + "(": string; + "]": string; + "[": string; + "{": string; + "}": string; + "<": string; + ">": string; + }; + $findOpeningBracket: (bracket: string, position: Point, typeRe?: RegExp) => Point | null; + $findClosingBracket: (bracket: string, position: Point, typeRe?: RegExp) => Point | null; + /** + * Returns [[Range]]'s for matching tags and tag names, if there are any + */ + getMatchingTags: (pos: Point) => { + closeTag: Range; + closeTagName: Range; + openTag: Range; + openTagName: Range; + }; + $findTagName: (iterator: any) => any; + $findClosingTag: (iterator: any, token: any) => { + openTag: Range; + closeTag: Range; + openTagName: Range; + closeTagName: Range; + }; + $findOpeningTag: (iterator: any, token: any) => { + openTag: Range; + closeTag: Range; + openTagName: Range; + closeTagName: Range; + }; + } + + interface IRange { + start: Point; + end: Point; + } + + interface LineWidget { + editor?: Editor, + el?: HTMLElement; + rowCount?: number; + hidden?: boolean; + _inDocument?: boolean; + column?: number; + row: number; + $oldWidget?: LineWidget, + session?: EditSession, + html?: string, + text?: string, + className?: string, + coverGutter?: boolean, + pixelHeight?: number, + $fold?: Fold, + type?: any, + destroy?: () => void; + coverLine?: boolean, + fixedWidth?: boolean, + fullWidth?: boolean, + screenWidth?: number, + rowsAbove?: number, + lenses?: CodeLenseCommand[], + } + + type NewLineMode = 'auto' | 'unix' | 'windows'; + + interface EditSessionOptions { + wrap: "off" | "free" | "printmargin" | boolean | number; + wrapMethod: 'code' | 'text' | 'auto'; + indentedSoftWrap: boolean; + firstLineNumber: number; + useWorker: boolean; + useSoftTabs: boolean; + tabSize: number; + navigateWithinSoftTabs: boolean; + foldStyle: 'markbegin' | 'markbeginend' | 'manual'; + overwrite: boolean; + newLineMode: NewLineMode; + mode: string; + } + + interface VirtualRendererOptions { + animatedScroll: boolean; + showInvisibles: boolean; + showPrintMargin: boolean; + printMarginColumn: number; + printMargin: boolean | number; + showGutter: boolean; + fadeFoldWidgets: boolean; + showFoldWidgets: boolean; + showLineNumbers: boolean; + displayIndentGuides: boolean; + highlightIndentGuides: boolean; + highlightGutterLine: boolean; + hScrollBarAlwaysVisible: boolean; + vScrollBarAlwaysVisible: boolean; + fontSize: string | number; + fontFamily: string; + maxLines: number; + minLines: number; + scrollPastEnd: number; + fixedWidthGutter: boolean; + customScrollbar: boolean; + theme: string; + hasCssTransforms: boolean; + maxPixelHeight: number; + useSvgGutterIcons: boolean; + showFoldedAnnotations: boolean; + useResizeObserver: boolean; + } + + interface MouseHandlerOptions { + scrollSpeed: number; + dragDelay: number; + dragEnabled: boolean; + focusTimeout: number; + } + + interface EditorOptions extends EditSessionOptions, + MouseHandlerOptions, + VirtualRendererOptions { + selectionStyle: "fullLine" | "screenLine" | "text" | "line"; + highlightActiveLine: boolean; + highlightSelectedWord: boolean; + readOnly: boolean; + copyWithEmptySelection: boolean; + cursorStyle: 'ace' | 'slim' | 'smooth' | 'wide'; + mergeUndoDeltas: true | false | 'always'; + behavioursEnabled: boolean; + wrapBehavioursEnabled: boolean; + enableAutoIndent: boolean; + enableBasicAutocompletion: boolean | Completer[]; + enableLiveAutocompletion: boolean | Completer[]; + liveAutocompletionDelay: number; + liveAutocompletionThreshold: number; + enableSnippets: boolean; + autoScrollEditorIntoView: boolean; + keyboardHandler: string | null; + placeholder: string; + value: string; + session: EditSession; + relativeLineNumbers: boolean; + enableMultiselect: boolean; + enableKeyboardAccessibility: boolean; + enableCodeLens: boolean; + textInputAriaLabel: string; + enableMobileMenu: boolean; + } + + interface EventsBase { + [key: string]: any; + } + + interface EditSessionEvents { + /** + * Emitted when the document changes. + * @param delta + */ + "change": (delta: Delta, emitter: EditSession) => void; + /** + * Emitted when the tab size changes, via [[EditSession.setTabSize]]. + */ + "changeTabSize": (e: undefined, emitter: EditSession) => void; + /** + * Emitted when the ability to overwrite text changes, via [[EditSession.setOverwrite]]. + * @param overwrite + */ + "changeOverwrite": (overwrite: boolean, emitter: EditSession) => void; + /** + * Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change. + * @param e + */ + "changeBreakpoint": (e: { row?: number, breakpoint?: boolean }, emitter: EditSession) => void; + /** + * Emitted when a front marker changes. + */ + "changeFrontMarker": (e: undefined, emitter: EditSession) => void; + /** + * Emitted when a back marker changes. + */ + "changeBackMarker": (e: undefined, emitter: EditSession) => void; + /** + * Emitted when an annotation changes, like through [[EditSession.setAnnotations]]. + */ + "changeAnnotation": (e: {}, emitter: EditSession) => void; + /** + * Emitted when a background tokenizer asynchronously processes new rows. + */ + "tokenizerUpdate": (e: { data: { first: number, last: number } }, emitter: EditSession) => void; + /** + * Emitted when the current mode changes. + * @param e + */ + "changeMode": (e: any, emitter: EditSession) => void; + /** + * Emitted when the wrap mode changes. + * @param e + */ + "changeWrapMode": (e: any, emitter: EditSession) => void; + /** + * Emitted when the wrapping limit changes. + * @param e + */ + "changeWrapLimit": (e: any, emitter: EditSession) => void; + /** + * Emitted when a code fold is added or removed. + * @param e + */ + "changeFold": (e: any, emitter: EditSession) => void; + /** + * Emitted when the scroll top changes. + * @param scrollTop The new scroll top value + **/ + "changeScrollTop": (scrollTop: number, emitter: EditSession) => void; + /** + * Emitted when the scroll left changes. + * @param scrollLeft The new scroll left value + **/ + "changeScrollLeft": (scrollLeft: number, emitter: EditSession) => void; + "changeEditor": (e: { editor?: Editor, oldEditor?: Editor }, emitter: EditSession) => void; + "changeSelection": (e: undefined, emitter: EditSession) => void; + "startOperation": (op: { command?: { name?: string }, args?: any }, emitter: EditSession) => void; + "endOperation": (op: any, emitter: EditSession) => void; + "beforeEndOperation": (e: undefined, emitter: EditSession) => void; + } + + interface EditorEvents { + "change": (delta: Delta, emitter: Editor) => void; + "changeSelection": (e: undefined, emitter: Editor) => void; + "input": (e: undefined, emitter: Editor) => void; + /** + * Emitted whenever the [[EditSession]] changes. + * @param e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s. + **/ + "changeSession": (e: { oldSession: EditSession, session: EditSession }, emitter: Editor) => void; + "blur": (e: any, emitter: Editor) => void; + "mousedown": (e: MouseEvent, emitter: Editor) => void; + "mousemove": (e: MouseEvent & { scrollTop?: any }, emitter: Editor) => void; + "changeStatus": (e: any, emitter: Editor) => void; + "keyboardActivity": (e: any, emitter: Editor) => void; + "mousewheel": (e: MouseEvent, emitter: Editor) => void; + "mouseup": (e: MouseEvent, emitter: Editor) => void; + "beforeEndOperation": (e: any, emitter: Editor) => void; + "nativecontextmenu": (e: any, emitter: Editor) => void; + "destroy": (e: any, emitter: Editor) => void; + "focus": (e: any, emitter: Editor) => void; + /** + * Emitted when text is copied. + * @param text The copied text + **/ + "copy": (e: { text: string }, emitter: Editor) => void; + /** + * Emitted when text is pasted. + **/ + "paste": (e: { text: string, event?: ClipboardEvent }, emitter: Editor) => void; + /** + * Emitted when the selection style changes, via [[Editor.setSelectionStyle]]. + * @param data Contains one property, `data`, which indicates the new selection style + **/ + "changeSelectionStyle": (data: "fullLine" | "screenLine" | "text" | "line", emitter: Editor) => void; + "changeMode": (e: { mode?: Ace.SyntaxMode, oldMode?: Ace.SyntaxMode }, emitter: Editor) => void; + + //from searchbox extension + "findSearchBox": (e: { match: boolean }, emitter: Editor) => void; + + //from code_lens extension + "codeLensClick": (e: any, emitter: Editor) => void; + + "select": (e: undefined, emitter: Editor) => void; + "gutterkeydown": (e: GutterKeyboardEvent, emitter: Editor) => void; + "gutterclick": (e: MouseEvent, emitter: Editor) => void; + "showGutterTooltip": (e: GutterTooltip, emitter: Editor) => void; + "hideGutterTooltip": (e: GutterTooltip, emitter: Editor) => void; + "compositionStart": (e: undefined, emitter: Editor) => void; + } + + interface AcePopupEvents { + "click": (e: MouseEvent, emitter: AcePopup) => void; + "dblclick": (e: MouseEvent, emitter: AcePopup) => void; + "tripleclick": (e: MouseEvent, emitter: AcePopup) => void; + "quadclick": (e: MouseEvent, emitter: AcePopup) => void; + "show": (e: undefined, emitter: AcePopup) => void; + "hide": (e: undefined, emitter: AcePopup) => void; + "select": (hide: boolean, emitter: AcePopup) => void; + "changeHoverMarker": (e: any, emitter: AcePopup) => void; + } + + interface DocumentEvents { + /** + * Fires whenever the document changes. + * Several methods trigger different `"change"` events. Below is a list of each action type, followed by each property that's also available: + * * `"insert"` + * * `range`: the [[Range]] of the change within the document + * * `lines`: the lines being added + * * `"remove"` + * * `range`: the [[Range]] of the change within the document + * * `lines`: the lines being removed + * + **/ + "change": (e: Delta, emitter: Document) => void; + "changeNewLineMode": (e: undefined, emitter: Document) => void; + } + + interface AnchorEvents { + /** + * Fires whenever the anchor position changes. + * Both of these objects have a `row` and `column` property corresponding to the position. + * Events that can trigger this function include [[Anchor.setPosition `setPosition()`]]. + * @param {Object} e An object containing information about the anchor position. It has two properties: + * - `old`: An object describing the old Anchor position + * - `value`: An object describing the new Anchor position + **/ + "change": (e: { old: Point, value: Point }, emitter: Anchor) => void; + } + + interface BackgroundTokenizerEvents { + /** + * Fires whenever the background tokeniziers between a range of rows are going to be updated. + * @param e An object containing two properties, `first` and `last`, which indicate the rows of the region being updated. + **/ + "update": (e: { + data: { first: number, last: number } + }, emitter: import("./src/background_tokenizer").BackgroundTokenizer) => void; + } + + interface SelectionEvents { + /** + * Emitted when the cursor position changes. + **/ + "changeCursor": (e: undefined, emitter: Selection) => void; + /** + * Emitted when the cursor selection changes. + **/ + "changeSelection": (e: undefined, emitter: Selection) => void; + } + + interface MultiSelectionEvents extends SelectionEvents { + "multiSelect": (e: undefined, emitter: Selection) => void; + "addRange": (e: { range: Range }, emitter: Selection) => void; + "removeRange": (e: { ranges: Range[] }, emitter: Selection) => void; + "singleSelect": (e: undefined, emitter: Selection) => void; + } + + interface PlaceHolderEvents { + "cursorEnter": (e: any, emitter: import("./src/placeholder").PlaceHolder) => void; + "cursorLeave": (e: any, emitter: import("./src/placeholder").PlaceHolder) => void; + } + + interface GutterEvents { + "changeGutterWidth": (width: number, emitter: import("./src/layer/gutter").Gutter) => void; + "afterRender": (e: undefined, emitter: import("./src/layer/gutter").Gutter) => void; + } + + interface TextEvents { + "changeCharacterSize": (e: any, emitter: import("./src/layer/text").Text) => void; + } + + interface VirtualRendererEvents { + "afterRender": (e: any, emitter: VirtualRenderer) => void; + "beforeRender": (e: any, emitter: VirtualRenderer) => void; + "themeLoaded": (e: { theme: string | Theme }, emitter: VirtualRenderer) => void; + "themeChange": (e: { theme: string | Theme }, emitter: VirtualRenderer) => void; + "scrollbarVisibilityChanged": (e: undefined, emitter: VirtualRenderer) => void; + "changeCharacterSize": (e: any, emitter: VirtualRenderer) => void; + "resize": (e: any, emitter: VirtualRenderer) => void; + "autosize": (e: undefined, emitter: VirtualRenderer) => void; + } + + type EmitParameters any> = + T extends (first: infer First, ...rest: any[]) => any + ? [First] + : []; + + export class EventEmitter any }> { + once(name: K, callback: T[K]): void; + + setDefaultHandler(name: string, callback: Function): void; + + removeDefaultHandler(name: string, callback: Function): void; + + on(name: K, callback: T[K], capturing?: boolean): T[K]; + + addEventListener(name: K, callback: T[K], capturing?: boolean): T[K]; + + off(name: K, callback: T[K]): void; + + removeListener(name: K, callback: T[K]): void; + + removeEventListener(name: K, callback: T[K]): void; + + removeAllListeners(name?: string): void; + + _signal(eventName: K, ...args: EmitParameters): void; + + _emit(eventName: K, ...args: EmitParameters): void; + + _dispatchEvent(eventName: K, ...args: EmitParameters): void; + } + + interface SearchOptions { + /**The string or regular expression you're looking for*/ + needle: string | RegExp; + preventScroll: boolean; + /**Whether to search backwards from where cursor currently is*/ + backwards: boolean; + /**The starting [[Range]] or cursor position to begin the search*/ + start: Range; + /**Whether or not to include the current line in the search*/ + skipCurrent: boolean; + /**The [[Range]] to search within. Set this to `null` for the whole document*/ + range: Range | null; + preserveCase: boolean; + /**Whether the search is a regular expression or not*/ + regExp: boolean; + /**Whether the search matches only on whole words*/ + wholeWord: boolean; + /**Whether the search ought to be case-sensitive*/ + caseSensitive: boolean; + /**Whether to wrap the search back to the beginning when it hits the end*/ + wrap: boolean; + re: any; + /**true, if needle has \n or \r\n*/ + $isMultiLine: boolean; + /** + * internal property, determine if browser supports unicode flag + * @private + * */ + $supportsUnicodeFlag: boolean; + } + + interface Point { + row: number; + column: number; + } + + type Position = Point; + + interface Delta { + action: 'insert' | 'remove'; + start: Point; + end: Point; + lines: string[]; + id?: number, + folds?: Fold[] + } + + interface Annotation { + row: number; + column: number; + text: string; + type: string; + } + + export interface MarkerGroupItem { + range: Range; + className: string; + } + + type MarkerGroup = import("./src/marker_group").MarkerGroup; + + + export interface Command { + name?: string; + bindKey?: string | { mac?: string, win?: string }; + readOnly?: boolean; + exec?: (editor?: Editor | any, args?: any) => void; + isAvailable?: (editor: Editor) => boolean; + description?: string, + multiSelectAction?: "forEach" | "forEachLine" | Function, + scrollIntoView?: true | "cursor" | "center" | "selectionPart" | "animate" | "selection" | "none", + aceCommandGroup?: string, + passEvent?: boolean, + level?: number, + action?: string, + } + + type CommandLike = Command | ((editor: Editor) => void) | ((sb: SearchBox) => void); + + type KeyboardHandler = Partial & { + attach?: (editor: Editor) => void; + detach?: (editor: Editor) => void; + getStatusText?: (editor?: any, data?: any) => string; + } + + export interface MarkerLike { + range?: Range; + type: string; + renderer?: MarkerRenderer; + clazz: string; + inFront?: boolean; + id?: number; + update?: (html: string[], + // TODO maybe define Marker class + marker: any, + session: EditSession, + config: any) => void; + + [key: string]: any; + } + + type MarkerRenderer = (html: string[], + range: Range, + left: number, + top: number, + config: any) => void; + + interface Token { + type: string; + value: string; + index?: number; + start?: number; + } + + type BaseCompletion = import("./src/autocomplete").BaseCompletion; + type SnippetCompletion = import("./src/autocomplete").SnippetCompletion; + type ValueCompletion = import("./src/autocomplete").ValueCompletion; + type Completion = import("./src/autocomplete").Completion; + + type HighlightRule = ({ defaultToken: string } | { include: string } | { todo: string } | { + token: string | string[] | ((value: string) => string); + regex: string | RegExp; + next?: string | (() => void); + push?: string; + comment?: string; + caseInsensitive?: boolean; + nextState?: string; + }) & { [key: string]: any }; + + type HighlightRulesMap = Record; + + type KeywordMapper = (keyword: string) => string; + + interface HighlightRules { + $rules: HighlightRulesMap; + $embeds: string[]; + $keywords: any[]; + $keywordList: string[]; + + addRules(rules: HighlightRulesMap, prefix?: string): void; + + getRules(): HighlightRulesMap; + + embedRules(rules: (new () => HighlightRules) | HighlightRulesMap, prefix: string, escapeRules?: boolean, append?: boolean): void; + + getEmbeds(): string[]; + + normalizeRules(): void; + + createKeywordMapper(map: Record, defaultToken?: string, ignoreCase?: boolean, splitChar?: string): KeywordMapper; + } + + type FoldWidget = "start" | "end" | "" + + interface FoldMode { + foldingStartMarker: RegExp; + foldingStopMarker?: RegExp; + + getFoldWidget(session: EditSession, foldStyle: string, row: number): FoldWidget; + + getFoldWidgetRange(session: EditSession, foldStyle: string, row: number): Range | undefined; + + indentationBlock(session: EditSession, row: number, column?: number): Range | undefined; + + openingBracketBlock(session: EditSession, bracket: string, row: number, column: number, typeRe?: RegExp): Range | undefined; + + closingBracketBlock(session: EditSession, bracket: string, row: number, column: number, typeRe?: RegExp): Range | undefined; + } + + type BehaviorAction = (state: string | string[], action: string, editor: Editor, session: EditSession, text: string | Range) => ({ + text: string, + selection: number[] + } | Range) & { [key: string]: any } | undefined; + type BehaviorMap = Record>; + + interface Behaviour { + $behaviours: { [behaviour: string]: any } + + add(name: string, action: string, callback: BehaviorAction): void; + + addBehaviours(behaviours: BehaviorMap): void; + + remove(name: string): void; + + inherit(mode: SyntaxMode | (new () => SyntaxMode), filter: string[]): void; + + getBehaviours(filter?: string[]): BehaviorMap; + } + + interface Outdent { + checkOutdent(line: string, input: string): boolean; + + autoOutdent(doc: Document, row: number): number | undefined; + } + + interface SyntaxMode { + /** + * quotes used by language mode + */ + $quotes: { [quote: string]: string }; + HighlightRules: { + new(config?: any): HighlightRules + }; //TODO: fix this + foldingRules?: FoldMode; + $behaviour?: Behaviour; + $defaultBehaviour?: Behaviour; + /** + * characters that indicate the start of a line comment + */ + lineCommentStart?: string; + /** + * characters that indicate the start and end of a block comment + */ + blockComment?: { start: string, end: string } + tokenRe?: RegExp; + nonTokenRe?: RegExp; + /** + * An object containing conditions to determine whether to apply matching quote or not. + */ + $pairQuotesAfter: { [quote: string]: RegExp } + $tokenizer: Tokenizer; + $highlightRules: HighlightRules; + $embeds?: string[]; + $modes?: SyntaxMode[]; + $keywordList?: string[]; + $highlightRuleConfig?: any; + completionKeywords: string[]; + transformAction: BehaviorAction; + path?: string; + + getTokenizer(): Tokenizer; + + toggleCommentLines(state: string | string[], + session: EditSession, + startRow: number, + endRow: number): void; + + toggleBlockComment(state: string | string[], + session: EditSession, + range: Range, + cursor: Point): void; + + getNextLineIndent(state: string | string[], line: string, tab: string): string; + + checkOutdent(state: string | string[], line: string, input: string): boolean; + + autoOutdent(state: string | string[], doc: EditSession, row: number): void; + + // TODO implement WorkerClient types + createWorker(session: EditSession): any; + + createModeDelegates(mapping: { [key: string]: string }): void; + + getKeywords(append?: boolean): Array; + + getCompletions(state: string | string[], + session: EditSession, + pos: Point, + prefix: string): Completion[]; + + $getIndent(line: string): string; + + $createKeywordList(): string[]; + + $delegator(method: string, args: IArguments, defaultHandler: any): any; + + } + + interface OptionsBase { + [key: string]: any; + } + + class OptionsProvider { + setOptions(optList: Partial): void; + + getOptions(optionNames?: Array | Partial): Partial; + + setOption(name: K, value: T[K]): void; + + getOption(name: K): T[K]; + } + + type KeyBinding = import("./src/keyboard/keybinding").KeyBinding; + + interface CommandMap { + [name: string]: Command; + } + + type execEventHandler = (obj: { + editor: Editor, + command: Command, + args: any[] + }, emitter: CommandManager) => void; + + interface CommandManagerEvents { + "exec": execEventHandler + "afterExec": execEventHandler; + "commandUnavailable": execEventHandler; + } + + type CommandManager = import("./src/commands/command_manager").CommandManager; + + + interface SavedSelection { + start: Point; + end: Point; + isBackwards: boolean; + } + + var Selection: { + new(session: EditSession): Selection; + } + + type CompleterCallback = (error: any, completions: Completion[]) => void; + + interface Completer { + /** Regular expressions defining valid identifier characters for completion triggers */ + identifierRegexps?: Array, + + /** Main completion method that provides suggestions for the given context */ + getCompletions(editor: Editor, + session: EditSession, + position: Point, + prefix: string, + callback: CompleterCallback): void; + + /** Returns documentation tooltip for a completion item */ + getDocTooltip?(item: Completion): void | string | Completion; + + /** Called when a completion item becomes visible */ + onSeen?: (editor: Ace.Editor, completion: Completion) => void; + /** Called when a completion item is inserted */ + onInsert?: (editor: Ace.Editor, completion: Completion) => void; + + /** Cleanup method called when completion is cancelled */ + cancel?(): void; + + /** Unique identifier for this completer */ + id?: string; + /** Characters that trigger autocompletion when typed */ + triggerCharacters?: string[]; + /** Whether to hide inline preview text */ + hideInlinePreview?: boolean; + /** Custom insertion handler for completion items */ + insertMatch?: (editor: Editor, data: Completion) => void; + } + + interface CompletionOptions { + matches?: Completion[]; + } + + type CompletionProviderOptions = { + exactMatch?: boolean; + ignoreCaption?: boolean; + } + + type GatherCompletionRecord = { + prefix: string; + matches: Completion[]; + finished: boolean; + } + + type CompletionCallbackFunction = (err: Error | undefined, data: GatherCompletionRecord) => void; + type CompletionProviderCallback = (this: import("./src/autocomplete").Autocomplete, err: Error | undefined, completions: import("./src/autocomplete").FilteredList, finished: boolean) => void; + + type AcePopupNavigation = "up" | "down" | "start" | "end"; + + interface EditorMultiSelectProperties { + inMultiSelectMode?: boolean, + /** + * Updates the cursor and marker layers. + **/ + updateSelectionMarkers: () => void, + /** + * Adds the selection and cursor. + * @param orientedRange A range containing a cursor + **/ + addSelectionMarker: (orientedRange: Ace.Range & { marker?: any }) => Ace.Range & { marker?: any }, + /** + * Removes the selection marker. + * @param range The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]]. + **/ + removeSelectionMarker: (range: Ace.Range & { marker?: any }) => void, + removeSelectionMarkers: (ranges: (Ace.Range & { marker?: any })[]) => void, + $onAddRange: (e: any) => void, + $onRemoveRange: (e: any) => void, + $onMultiSelect: (e: any) => void, + $onSingleSelect: (e: any) => void, + $onMultiSelectExec: (e: any) => void, + /** + * Executes a command for each selection range. + * @param cmd The command to execute + * @param [args] Any arguments for the command + **/ + forEachSelection: (cmd: Object, args?: string, options?: Object) => void, + /** + * Removes all the selections except the last added one. + **/ + exitMultiSelectMode: () => void, + getSelectedText: () => string, + $checkMultiselectChange: (e: any, anchor: Ace.Anchor) => void, + /** + * Finds and selects all the occurrences of `needle`. + * @param needle The text to find + * @param options The search options + * @param additive keeps + * @returns {Number} The cumulative count of all found matches + **/ + findAll: (needle?: string, options?: Partial, additive?: boolean) => number, + /** + * Adds a cursor above or below the active cursor. + * @param dir The direction of lines to select: -1 for up, 1 for down + * @param [skip] If `true`, removes the active selection range + */ + selectMoreLines: (dir: number, skip?: boolean) => void, + /** + * Transposes the selected ranges. + * @param {Number} dir The direction to rotate selections + **/ + transposeSelections: (dir: number) => void, + /** + * Finds the next occurrence of text in an active selection and adds it to the selections. + * @param {Number} dir The direction of lines to select: -1 for up, 1 for down + * @param {Boolean} [skip] If `true`, removes the active selection range + * @param {Boolean} [stopAtFirst] + **/ + selectMore: (dir: number, skip?: boolean, stopAtFirst?: boolean) => void, + /** + * Aligns the cursors or selected text. + **/ + alignCursors: () => void, + $reAlignText: (lines: string[], forceLeft: boolean) => string[], + multiSelect?: any, + $multiselectOnSessionChange?: any, + $blockSelectEnabled?: boolean, + } + + /** + * Provider interface for code lens functionality + */ + interface CodeLenseProvider { + /** + * Compute code lenses for the given edit session + * @param session The edit session to provide code lenses for + * @param callback Callback function that receives errors and code lenses + */ + provideCodeLenses: (session: EditSession, callback: (err: any, payload: CodeLense[]) => void) => void; + } + + /** + * Represents a command associated with a code lens + */ + interface CodeLenseCommand { + /** + * Command identifier that will be executed + */ + id?: string, + /** + * Display title for the code lens + */ + title: string, + /** + * Argument(s) to pass to the command when executed + */ + arguments?: any, + } + + /** + * Represents a code lens - an actionable UI element displayed above a code line + */ + interface CodeLense { + /** + * Starting position where the code lens should be displayed + */ + start: Point, + /** + * Command to execute when the code lens is activated + */ + command?: CodeLenseCommand + } + + interface CodeLenseEditorExtension { + codeLensProviders?: CodeLenseProvider[]; + $codeLensClickHandler?: any; + $updateLenses?: () => void; + $updateLensesOnInput?: () => void; + } + + interface ElasticTabstopsEditorExtension { + elasticTabstops?: import("./src/ext/elastic_tabstops_lite").ElasticTabstopsLite; + } + + interface TextareaEditorExtension { + setDisplaySettings?: (settings: any) => void; + } + + interface PromptEditorExtension { + cmdLine?: Editor; + } + + interface OptionsEditorExtension { + $options?: any; + } + + interface MultiSelectProperties { + ranges: Ace.Range[] | null; + rangeList: Ace.RangeList | null; + + /** + * Adds a range to a selection by entering multiselect mode, if necessary. + * @param {Ace.Range} range The new range to add + * @param {Boolean} [$blockChangeEvents] Whether or not to block changing events + **/ + addRange(range: Ace.Range, $blockChangeEvents?: boolean): any; + + inMultiSelectMode: boolean; + + /** + * @param {Ace.Range} [range] + **/ + toSingleRange(range?: Ace.Range): void; + + /** + * Removes a Range containing pos (if it exists). + * @param {Ace.Point} pos The position to remove, as a `{row, column}` object + **/ + substractPoint(pos: Ace.Point): any; + + /** + * Merges overlapping ranges ensuring consistency after changes + **/ + mergeOverlappingRanges(): void; + + /** + * @param {Ace.Range} range + */ + $onAddRange(range: Ace.Range): void; + + rangeCount: number; + + /** + * + * @param {Ace.Range[]} removed + */ + $onRemoveRange(removed: Ace.Range[]): void; + + /** + * adds multicursor support to selection + */ + $initRangeList(): void; + + /** + * Returns a concatenation of all the ranges. + * @returns {Ace.Range[]} + **/ + getAllRanges(): Ace.Range[]; + + /** + * Splits all the ranges into lines. + **/ + splitIntoLines(): void; + + /** + */ + joinSelections(): void; + + /** + **/ + toggleBlockSelection(): void; + + /** + * + * Gets list of ranges composing rectangular block on the screen + * + * @param {Ace.ScreenCoordinates} screenCursor The cursor to use + * @param {Ace.ScreenCoordinates} screenAnchor The anchor to use + * @param {Boolean} [includeEmptyLines] If true, this includes ranges inside the block which are empty due to clipping + * @returns {Ace.Range[]} + **/ + rectangularRangeBlock(screenCursor: Ace.ScreenCoordinates, screenAnchor: Ace.ScreenCoordinates, includeEmptyLines?: boolean): Ace.Range[]; + + _eventRegistry?: any; + index?: number; + } + + type AcePopupEventsCombined = Ace.EditorEvents & Ace.AcePopupEvents; + type AcePopupWithEditor = Ace.EventEmitter & Ace.Editor; + type InlineAutocompleteAction = "prev" | "next" | "first" | "last"; + + type TooltipCommandFunction = (editor: Ace.Editor) => T; + + export interface TooltipCommand extends Ace.Command { + enabled?: TooltipCommandFunction | boolean, + getValue?: TooltipCommandFunction, + type: "button" | "text" | "checkbox" + iconCssClass?: string, + cssClass?: string + } + + export type CommandBarTooltip = import("./src/ext/command_bar").CommandBarTooltip; + + export type TokenizeResult = Array> + + export interface StaticHighlightOptions { + /** Syntax mode (e.g., 'ace/mode/javascript'). Auto-detected from CSS class if not provided */ + mode?: string | SyntaxMode, + /** Color theme (e.g., 'ace/theme/textmate'). Defaults to 'ace/theme/textmate' */ + theme?: string | Theme, + /** Whether to trim whitespace from code content */ + trim?: boolean, + /** Starting line number for display */ + firstLineNumber?: number, + /** Whether to show line numbers gutter */ + showGutter?: boolean + } + + export interface Operation { + command: { + name?: string; + }; + args: any; + selectionBefore?: Range | Range[]; + selectionAfter?: Range | Range[]; + docChanged?: boolean; + selectionChanged?: boolean; + } + + export interface CommandBarEvents { + "hide": (e: undefined, emitter: import("./src/ext/command_bar").CommandBarTooltip) => void; + "show": (e: undefined, emitter: import("./src/ext/command_bar").CommandBarTooltip) => void; + "alwaysShow": (e: boolean, emitter: import("./src/ext/command_bar").CommandBarTooltip) => void; + } + + export interface FontMetricsEvents { + "changeCharacterSize": (e: { data: { height: number, width: number } }, emitter: import("./src/layer/font_metrics").FontMetrics) => void; + } + + export interface OptionPanelEvents { + "setOption": (e: { name: string, value: any }, emitter: import("./src/ext/options").OptionPanel) => void; + } + + export interface ScrollbarEvents { + "scroll": (e: { data: number }, emitter: ScrollBar) => void; + } + + export interface TextInputAriaOptions { + activeDescendant?: string; + role?: string; + setLabel?: boolean; + inline?: boolean; + } +} + + +export const version: string; +export const config: Ace.Config; + +export function require(name: string): any; + +export function edit(el?: string | (Element & { + env?: any; + value?: any; +}) | null, options?: Partial): Ace.Editor; + +export function createEditSession(text: Ace.Document | string, mode: Ace.SyntaxMode): Ace.EditSession; + +export const VirtualRenderer: { + new(container: HTMLElement, theme?: string): Ace.VirtualRenderer; +}; +export const EditSession: { + new(text: string | Ace.Document, mode?: Ace.SyntaxMode): Ace.EditSession; +}; +export const UndoManager: { + new(): Ace.UndoManager; +}; +export const Editor: { + new(renderer: Ace.VirtualRenderer, session?: Ace.EditSession, options?: Partial): Ace.Editor; +}; +export const Range: { + new(startRow: number, startColumn: number, endRow: number, endColumn: number): Ace.Range; + fromPoints(start: Ace.Point, end: Ace.Point): Ace.Range; + comparePoints(p1: Ace.Point, p2: Ace.Point): number; +}; + +export type InlineAutocomplete = Ace.InlineAutocomplete; +export type CommandBarTooltip = Ace.CommandBarTooltip; + +declare global { + interface Element { + setAttribute(name: string, value: boolean): void; + + setAttribute(name: string, value: number): void; + } +} + +declare module "./src/anchor" { + export interface Anchor extends Ace.EventEmitter { + markerId?: number; + document: Ace.Document; + } + + +} + +declare module "./src/autocomplete" { + export interface Autocomplete { + popup: Ace.AcePopup; + emptyMessage?: Function, + } + + export interface CompletionProvider { + completions: Ace.FilteredList; + } +} + +declare module "./src/background_tokenizer" { + export interface BackgroundTokenizer extends Ace.EventEmitter { + + } +} + +declare module "./src/document" { + export interface Document extends Ace.EventEmitter { + } + +} + +declare module "./src/editor" { + export interface Editor extends Ace.EditorMultiSelectProperties, Ace.OptionsProvider, + Ace.EventEmitter, Ace.CodeLenseEditorExtension, Ace.ElasticTabstopsEditorExtension, + Ace.TextareaEditorExtension, Ace.PromptEditorExtension, Ace.OptionsEditorExtension { + session: Ace.EditSession; + $mergeUndoDeltas?: any, + $highlightSelectedWord?: boolean, + $updatePlaceholder?: Function, + $cursorStyle?: string, + $readOnly?: any, + $highlightActiveLine?: any, + $enableAutoIndent?: any, + $copyWithEmptySelection?: any + $selectionStyle?: string, + env?: any; + widgetManager?: Ace.LineWidgets, + completer?: Ace.Autocomplete | Ace.InlineAutocomplete, + completers: Ace.Completer[], + $highlightTagPending?: boolean, + showKeyboardShortcuts?: () => void, + showSettingsMenu?: () => void, + searchBox?: Ace.SearchBox, + _eventRegistry?: any, + $textInputAriaLabel?: string + } +} + +declare module "./src/edit_session" { + type TextMarker = import("./src/layer/text_markers").TextMarker; + type TextMarkers = typeof import("./src/layer/text_markers").editSessionTextMarkerMixin & { + $textMarkers: TextMarker[]; + $textMarkerId: number; + $scheduleForRemove: Set; + }; + + export interface EditSession extends Ace.EventEmitter, + Ace.OptionsProvider, + Ace.Folding, Ace.BracketMatch, TextMarkers { + doc: Ace.Document, + $highlightLineMarker?: { + start: Ace.Point, + end: Ace.Point, + id?: number + } + $useSoftTabs?: boolean, + $tabSize?: number, + $useWorker?: boolean, + $wrapAsCode?: boolean, + $indentedSoftWrap?: boolean, + $bracketHighlight?: any, + $selectionMarker?: number, + lineWidgetsWidth?: number, + $getWidgetScreenLength?: () => number, + _changedWidgets?: any, + $options: any, + $wrapMethod?: any, + $enableVarChar?: any, + $wrap?: any, + $navigateWithinSoftTabs?: boolean, + $selectionMarkers?: any[], + gutterRenderer?: any, + $firstLineNumber?: number, + $emacsMark?: any, + selectionMarkerCount?: number, + multiSelect?: any, + $occurHighlight?: any, + $occur?: Ace.Occur, + $occurMatchingLines?: any, + $useEmacsStyleLineStart?: boolean, + $selectLongWords?: boolean, + curOp: Ace.Operation | null, + + getSelectionMarkers(): any[], + } + +} + +declare module "./src/edit_session/fold" { + export interface Fold { + collapseChildren?: number; + } +} + +declare module "./src/placeholder" { + export interface PlaceHolder extends Ace.EventEmitter { + } +} + +declare module "./src/scrollbar" { + export interface VScrollBar extends Ace.EventEmitter { + } + + export interface HScrollBar extends Ace.EventEmitter { + } +} + +declare module "./src/scrollbar_custom" { + export interface VScrollBar extends Ace.EventEmitter { + } + + export interface HScrollBar extends Ace.EventEmitter { + } +} + +declare module "./src/line_widgets" { + export interface LineWidgets { + lineWidgets: Ace.LineWidget[]; + editor: Ace.Editor; + } +} + +declare module "./src/selection" { + export interface Selection extends Ace.EventEmitter, Ace.MultiSelectProperties { + } +} + +declare module "./src/range" { + export interface Range { + id?: number; + cursor?: Ace.Point; + isBackwards?: boolean; + } +} + +declare module "./src/virtual_renderer" { + export interface VirtualRenderer extends Ace.EventEmitter, Ace.OptionsProvider { + $customScrollbar?: boolean, + $extraHeight?: number, + $showGutter?: boolean, + $showPrintMargin?: boolean, + $printMarginColumn?: number, + $animatedScroll?: boolean, + $isMousePressed?: boolean, + textarea: HTMLTextAreaElement, + $hScrollBarAlwaysVisible?: boolean, + $vScrollBarAlwaysVisible?: boolean + $maxLines?: number, + $scrollPastEnd?: number, + enableKeyboardAccessibility?: boolean, + $highlightGutterLine?: boolean, + $minLines?: number, + $maxPixelHeight?: number, + $gutterWidth?: number, + showInvisibles?: boolean, + $hasCssTransforms?: boolean, + $blockCursor?: boolean, + $useTextareaForIME?: boolean, + theme?: any, + $theme?: any, + destroyed?: boolean, + session: Ace.EditSession, + keyboardFocusClassName?: string, + } +} + +declare module "./src/snippets" { + interface SnippetManager extends Ace.EventEmitter { + } +} + +declare module "./src/ext/command_bar" { + export interface CommandBarTooltip extends Ace.EventEmitter { + $shouldHideMoreOptions?: boolean, + } +} + +declare module "./src/commands/command_manager" { + export interface CommandManager extends Ace.EventEmitter { + $checkCommandState?: boolean + } +} + +declare module "./src/autocomplete/popup" { + + export interface AcePopup extends Ace.AcePopupWithEditor { + setSelectOnHover: (val: boolean) => void, + setRow: (line: number) => void, + getRow: () => number, + getHoveredRow: () => number, + filterText: string, + isOpen: boolean, + isTopdown: boolean, + autoSelect: boolean, + data: Ace.Completion[], + setData: (data: Ace.Completion[], filterText?: string) => void, + getData: (row: number) => Ace.Completion, + hide: () => void, + anchor: "top" | "bottom", + anchorPosition: Ace.Point, + tryShow: (pos: any, lineHeight: number, anchor: "top" | "bottom", forceShow?: boolean) => boolean, + $borderSize: number, + show: (pos: any, lineHeight: number, topdownOnly?: boolean) => void, + goTo: (where: Ace.AcePopupNavigation) => void, + getTextLeftOffset: () => number, + $imageSize: number, + anchorPos: any, + isMouseOver?: boolean, + selectedNode?: HTMLElement, + } +} + +declare module "./src/layer/cursor" { + export interface Cursor { + timeoutId?: number; + } +} + +declare module "./src/layer/gutter" { + export interface Gutter extends Ace.EventEmitter { + $useSvgGutterIcons?: boolean, + $showFoldedAnnotations?: boolean, + } +} + +declare module "./src/layer/text" { + type TextMarkersMixin = typeof import("./src/layer/text_markers").textMarkerMixin; + export interface Text extends Ace.EventEmitter, TextMarkersMixin { + config: Ace.LayerConfig + } +} + +declare module "./src/lib/app_config" { + export interface AppConfig extends Ace.EventEmitter { + } +} + +declare module "./src/mouse/mouse_event" { + export interface MouseEvent { + time?: number; + } +} + +declare module "./src/mouse/mouse_handler" { + + export interface MouseHandler { + cancelDrag?: boolean + //from DefaultHandlers + $clickSelection?: Ace.Range, + mousedownEvent?: Ace.MouseEvent, + startSelect?: (pos?: Ace.Point, waitForClickSelection?: boolean) => void, + select?: () => void + $lastScroll?: { t: number, vx: number, vy: number, allowed: number } + selectEnd?: () => void + $tooltip?: Ace.GutterTooltip + } +} + +declare module "./src/ext/options" { + export interface OptionPanel extends Ace.EventEmitter { + } +} + +declare module "./src/layer/font_metrics" { + export interface FontMetrics extends Ace.EventEmitter { + } +} + +declare module "./src/tooltip" { + export interface HoverTooltip { + row: number; + } +} + +declare module "./src/mouse/default_gutter_handler" { + export interface GutterHandler { + } +} + +declare module "./src/ext/diff/base_diff_view" { + export interface BaseDiffView extends Ace.OptionsProvider { + } +} + diff --git a/ace-modes.d.ts b/ace-modes.d.ts new file mode 100644 index 00000000000..8bf991f2bb8 --- /dev/null +++ b/ace-modes.d.ts @@ -0,0 +1,1736 @@ +declare module "ace-code/src/mode/abap_highlight_rules" { + export const AbapHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/abap" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/abc_highlight_rules" { + export const ABCHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/abc" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/actionscript_highlight_rules" { + export const ActionScriptHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/actionscript" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/ada_highlight_rules" { + export const AdaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/ada" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/alda_highlight_rules" { + export const AldaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/alda" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/apache_conf_highlight_rules" { + export const ApacheConfHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/apache_conf" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/apex_highlight_rules" { + export const ApexHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/apex" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/applescript_highlight_rules" { + export const AppleScriptHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/applescript" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/aql_highlight_rules" { + export const AqlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/aql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/asciidoc_highlight_rules" { + export const AsciidocHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/asciidoc" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/asl_highlight_rules" { + export const ASLHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/asl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/assembly_arm32_highlight_rules" { + export const AssemblyARM32HighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/assembly_arm32" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/assembly_x86_highlight_rules" { + export const AssemblyX86HighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/assembly_x86" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/astro_highlight_rules" { + export const AstroHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/astro" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/autohotkey_highlight_rules" { + export const AutoHotKeyHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/autohotkey" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/basic_highlight_rules" { + export const BasicHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/basic" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/batchfile_highlight_rules" { + export const BatchFileHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/batchfile" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/behaviour" { + export const Behaviour: new () => import("ace-code").Ace.Behaviour; +} + +declare module "ace-code/src/mode/behaviour/css" { + export const CssBehaviour: new () => import("ace-code").Ace.Behaviour; +} + +declare module "ace-code/src/mode/behaviour/cstyle" { + export const CstyleBehaviour: new () => import("ace-code").Ace.Behaviour; +} + +declare module "ace-code/src/mode/behaviour/html" { + export const HtmlBehaviour: new () => import("ace-code").Ace.Behaviour; +} + +declare module "ace-code/src/mode/behaviour/javascript" { + export const JavaScriptBehaviour: new () => import("ace-code").Ace.Behaviour; +} + +declare module "ace-code/src/mode/behaviour/liquid" { + export const LiquidBehaviour: new () => import("ace-code").Ace.Behaviour; +} + +declare module "ace-code/src/mode/behaviour/xml" { + export const XmlBehaviour: new () => import("ace-code").Ace.Behaviour; +} + +declare module "ace-code/src/mode/behaviour/xquery" { + export const XQueryBehaviour: new () => import("ace-code").Ace.Behaviour; +} + +declare module "ace-code/src/mode/bibtex_highlight_rules" { + export const BibTeXHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/bibtex" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/c_cpp_highlight_rules" { + export const cFunctions: string; + export const c_cppHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/c_cpp" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/c9search_highlight_rules" { + export const C9SearchHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/c9search" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/cirru_highlight_rules" { + export const CirruHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/cirru" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/clojure_highlight_rules" { + export const ClojureHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/clojure" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/clue_highlight_rules" { + export const ClueHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/clue" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/cobol_highlight_rules" { + export const CobolHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/cobol" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/coffee_highlight_rules" { + export const CoffeeHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/coffee" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/coldfusion_highlight_rules" { + export const ColdfusionHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/coldfusion" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/crystal_highlight_rules" { + export const CrystalHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/crystal" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/csharp_highlight_rules" { + export const CSharpHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/csharp" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/csound_document_highlight_rules" { + export const CsoundDocumentHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/csound_document" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/csound_orchestra_highlight_rules" { + export const CsoundOrchestraHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/csound_orchestra" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/csound_preprocessor_highlight_rules" { + export const CsoundPreprocessorHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/csound_score_highlight_rules" { + export const CsoundScoreHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/csound_score" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/csp_highlight_rules" { + export const CspHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/csp" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/css_completions" { + export const CssCompletions: new () => import("ace-code").Ace.Completion; +} + +declare module "ace-code/src/mode/css_highlight_rules" { + export const supportType: string; + export const supportFunction: string; + export const supportConstant: string; + export const supportConstantColor: string; + export const supportConstantFonts: string; + export const numRe: string; + export const pseudoElements: string; + export const pseudoClasses: string; + export const CssHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/css" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/csv_highlight_rules" { + export const CsvHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/csv" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/curly_highlight_rules" { + export const CurlyHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/curly" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/cuttlefish_highlight_rules" { + export const CuttlefishHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/cuttlefish" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/d_highlight_rules" { + export const DHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/d" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/dart_highlight_rules" { + export const DartHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/dart" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/diff_highlight_rules" { + export const DiffHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/diff" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/django" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/doc_comment_highlight_rules" { + export const DocCommentHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/dockerfile_highlight_rules" { + export const DockerfileHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/dockerfile" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/dot_highlight_rules" { + export const DotHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/dot" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/drools_highlight_rules" { + export const DroolsHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/drools" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/edifact_highlight_rules" { + export const EdifactHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/edifact" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/eiffel_highlight_rules" { + export const EiffelHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/eiffel" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/ejs" { + export const EjsHighlightRules: new () => import("ace-code").Ace.HighlightRules; + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/elixir_highlight_rules" { + export const ElixirHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/elixir" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/elm_highlight_rules" { + export const ElmHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/elm" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/erlang_highlight_rules" { + export const ErlangHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/erlang" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/flix_highlight_rules" { + export const FlixHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/flix" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/folding/asciidoc" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/basic" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/c9search" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/coffee" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/csharp" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/cstyle" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/diff" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/drools" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/fold_mode" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/haskell_cabal" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/html" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/ini" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/java" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/javascript" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/latex" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/lua" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/markdown" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/mixed" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/nunjucks" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/php" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/pythonic" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/ruby" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/sql" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/sqlserver" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/vbscript" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/velocity" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/xml" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/folding/yaml" { + export const FoldMode: new () => import("ace-code").Ace.Folding; +} + +declare module "ace-code/src/mode/forth_highlight_rules" { + export const ForthHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/forth" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/fortran_highlight_rules" { + export const FortranHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/fortran" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/fsharp_highlight_rules" { + export const FSharpHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/fsharp" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/fsl_highlight_rules" { + export const FSLHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/fsl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/ftl_highlight_rules" { + export const FtlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/ftl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/gcode_highlight_rules" { + export const GcodeHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/gcode" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/gherkin_highlight_rules" { + export const GherkinHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/gherkin" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/gitignore_highlight_rules" { + export const GitignoreHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/gitignore" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/glsl_highlight_rules" { + export const glslHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/glsl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/gobstones_highlight_rules" { + export const GobstonesHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/gobstones" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/golang_highlight_rules" { + export const GolangHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/golang" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/graphqlschema_highlight_rules" { + export const GraphQLSchemaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/graphqlschema" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/groovy_highlight_rules" { + export const GroovyHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/groovy" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/haml_highlight_rules" { + export const HamlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/haml" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/handlebars_highlight_rules" { + export const HandlebarsHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/handlebars" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/haskell_cabal_highlight_rules" { + export const CabalHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/haskell_cabal" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/haskell_highlight_rules" { + export const HaskellHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/haskell" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/haxe_highlight_rules" { + export const HaxeHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/haxe" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/hjson_highlight_rules" { + export const HjsonHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/hjson" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/html_completions" { + export const HtmlCompletions: new () => import("ace-code").Ace.Completion; +} + +declare module "ace-code/src/mode/html_elixir_highlight_rules" { + export const HtmlElixirHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/html_elixir" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/html_highlight_rules" { + export const HtmlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/html_ruby_highlight_rules" { + export const HtmlRubyHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/html_ruby" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/html" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/ini_highlight_rules" { + export const IniHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/ini" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/io_highlight_rules" { + export const IoHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/io" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/ion_highlight_rules" { + export const IonHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/ion" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/jack_highlight_rules" { + export const JackHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/jack" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/jade_highlight_rules" { + export const JadeHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/jade" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/java_highlight_rules" { + export const JavaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/java" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/javascript_highlight_rules" { + export const JavaScriptHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/javascript" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/jexl_highlight_rules" { + export const JexlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/jexl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/js_regex_highlight_rules" { + export const JsRegexHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/jsdoc_comment_highlight_rules" { + export const JsDocCommentHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/json_highlight_rules" { + export const JsonHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/json" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/json5_highlight_rules" { + export const Json5HighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/json5" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/jsp_highlight_rules" { + export const JspHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/jsp" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/jssm_highlight_rules" { + export const JSSMHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/jssm" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/jsx_highlight_rules" { + export const JsxHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/jsx" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/julia_highlight_rules" { + export const JuliaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/julia" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/kotlin_highlight_rules" { + export const KotlinHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/kotlin" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/latex_highlight_rules" { + export const LatexHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/latex" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/latte_highlight_rules" { + export const LatteHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/latte" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/less_highlight_rules" { + export const LessHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/less" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/liquid_highlight_rules" { + export const LiquidHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/liquid" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/lisp_highlight_rules" { + export const LispHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/lisp" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/livescript" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/logiql_highlight_rules" { + export const LogiQLHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/logiql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/logtalk_highlight_rules" { + export const LogtalkHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/logtalk" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/lsl_highlight_rules" { + export const LSLHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/lsl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/lua_highlight_rules" { + export const LuaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/lua" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/luapage_highlight_rules" { + export const LuaPageHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/luapage" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/lucene_highlight_rules" { + export const LuceneHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/lucene" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/makefile_highlight_rules" { + export const MakefileHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/makefile" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/markdown_highlight_rules" { + export const MarkdownHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/markdown" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/mask_highlight_rules" { + export const MaskHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/mask" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/matching_brace_outdent" { + export const MatchingBraceOutdent: new () => import("ace-code").Ace.Outdent; +} + +declare module "ace-code/src/mode/matching_parens_outdent" { + export const MatchingParensOutdent: new () => import("ace-code").Ace.Outdent; +} + +declare module "ace-code/src/mode/matlab_highlight_rules" { + export const MatlabHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/matlab" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/maze_highlight_rules" { + export const MazeHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/maze" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/mediawiki_highlight_rules" { + export const MediaWikiHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/mediawiki" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/mel_highlight_rules" { + export const MELHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/mel" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/mips_highlight_rules" { + export const MIPSHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/mips" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/mixal_highlight_rules" { + export const MixalHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/mixal" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/mushcode_highlight_rules" { + export const MushCodeRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/mushcode" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/mysql_highlight_rules" { + export const MysqlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/mysql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/nasal_highlight_rules" { + export const NasalHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/nasal" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/nginx_highlight_rules" { + export const NginxHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/nginx" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/nim_highlight_rules" { + export const NimHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/nim" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/nix_highlight_rules" { + export const NixHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/nix" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/nsis_highlight_rules" { + export const NSISHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/nsis" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/nunjucks_highlight_rules" { + export const NunjucksHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/nunjucks" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/objectivec_highlight_rules" { + export const ObjectiveCHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/objectivec" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/ocaml_highlight_rules" { + export const OcamlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/ocaml" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/odin_highlight_rules" { + export const OdinHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/odin" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/partiql_highlight_rules" { + export const PartiqlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/partiql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/pascal_highlight_rules" { + export const PascalHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/pascal" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/perl_highlight_rules" { + export const PerlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/perl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/pgsql_highlight_rules" { + export const PgsqlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/pgsql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/php_completions" { + export const PhpCompletions: new () => import("ace-code").Ace.Completion; +} + +declare module "ace-code/src/mode/php_highlight_rules" { + export const PhpHighlightRules: new () => import("ace-code").Ace.HighlightRules; + export const PhpLangHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/php_laravel_blade_highlight_rules" { + export const PHPLaravelBladeHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/php_laravel_blade" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/php" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/pig_highlight_rules" { + export const PigHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/pig" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/plain_text" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/plsql_highlight_rules" { + export const plsqlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/plsql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/powershell_highlight_rules" { + export const PowershellHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/powershell" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/praat_highlight_rules" { + export const PraatHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/praat" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/prisma_highlight_rules" { + export const PrismaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/prisma" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/prolog_highlight_rules" { + export const PrologHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/prolog" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/properties_highlight_rules" { + export const PropertiesHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/properties" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/protobuf_highlight_rules" { + export const ProtobufHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/protobuf" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/prql_highlight_rules" { + export const PrqlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/prql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/puppet_highlight_rules" { + export const PuppetHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/puppet" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/python_highlight_rules" { + export const PythonHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/python" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/qml_highlight_rules" { + export const QmlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/qml" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/r_highlight_rules" { + export const RHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/r" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/raku_highlight_rules" { + export const RakuHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/raku" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/razor_completions" { + export const RazorCompletions: new () => import("ace-code").Ace.Completion; +} + +declare module "ace-code/src/mode/razor_highlight_rules" { + export const RazorHighlightRules: new () => import("ace-code").Ace.HighlightRules; + export const RazorLangHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/razor" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/rdoc_highlight_rules" { + export const RDocHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/rdoc" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/red_highlight_rules" { + export const RedHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/red" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/redshift_highlight_rules" { + export const RedshiftHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/redshift" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/rhtml_highlight_rules" { + export const RHtmlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/rhtml" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/robot_highlight_rules" { + export const RobotHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/robot" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/rst_highlight_rules" { + export const RSTHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/rst" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/ruby_highlight_rules" { + export const constantOtherSymbol: { token: string; regex: string; }; + export const qString: { token: string; regex: string; }; + export const qqString: { token: string; regex: string; }; + export const tString: { token: string; regex: string; }; + export const constantNumericHex: { token: string; regex: string; }; + export const constantNumericBinary: { token: string; regex: RegExp; }; + export const constantNumericDecimal: { token: string; regex: RegExp; }; + export const constantNumericOctal: { token: string; regex: RegExp; }; + export const constantNumericRational: { token: string; regex: RegExp; }; + export const constantNumericComplex: { token: string; regex: RegExp; }; + export const constantNumericFloat: { token: string; regex: string; }; + export const instanceVariable: { token: string; regex: string; }; + export const RubyHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/ruby" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/rust_highlight_rules" { + export const RustHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/rust" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/sac_highlight_rules" { + export const sacHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/sac" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/sass_highlight_rules" { + export const SassHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/sass" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/scad_highlight_rules" { + export const scadHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/scad" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/scala_highlight_rules" { + export const ScalaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/scala" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/scheme_highlight_rules" { + export const SchemeHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/scheme" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/scrypt_highlight_rules" { + export const scryptHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/scrypt" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/scss_highlight_rules" { + export const ScssHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/scss" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/sh_highlight_rules" { + export const reservedKeywords: string; + export const languageConstructs: string; + export const ShHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/sh" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/sjs_highlight_rules" { + export const SJSHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/sjs" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/slim_highlight_rules" { + export const SlimHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/slim" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/smarty_highlight_rules" { + export const SmartyHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/smarty" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/smithy_highlight_rules" { + export const SmithyHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/smithy" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/snippets" { + export const SnippetHighlightRules: new () => import("ace-code").Ace.HighlightRules; + export const SnippetGroupHighlightRules: new () => import("ace-code").Ace.HighlightRules; + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/soy_template_highlight_rules" { + export const SoyTemplateHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/soy_template" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/space_highlight_rules" { + export const SpaceHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/space" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/sparql_highlight_rules" { + export const SPARQLHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/sparql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/sql_highlight_rules" { + export const SqlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/sql" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/sqlserver_highlight_rules" { + export const SqlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/sqlserver" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/stylus_highlight_rules" { + export const StylusHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/stylus" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/svg_highlight_rules" { + export const SvgHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/svg" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/swift_highlight_rules" { + export const HighlightRules: new () => import("ace-code").Ace.HighlightRules; + export const SwiftHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/swift" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/tcl_highlight_rules" { + export const TclHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/tcl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/terraform_highlight_rules" { + export const TerraformHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/terraform" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/tex_highlight_rules" { + export const TexHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/tex" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/text_highlight_rules" { + export const TextHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/text" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/textile_highlight_rules" { + export const TextileHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/textile" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/toml_highlight_rules" { + export const TomlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/toml" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/tsv_highlight_rules" { + export const TsvHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/tsv" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/tsx_highlight_rules" { + export const TsxHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/tsx" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/turtle_highlight_rules" { + export const TurtleHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/turtle" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/twig_highlight_rules" { + export const TwigHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/twig" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/typescript_highlight_rules" { + export const TypeScriptHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/typescript" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/vala_highlight_rules" { + export const ValaHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/vala" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/vbscript_highlight_rules" { + export const VBScriptHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/vbscript" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/velocity_highlight_rules" { + export const VelocityHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/velocity" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/verilog_highlight_rules" { + export const VerilogHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/verilog" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/vhdl_highlight_rules" { + export const VHDLHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/vhdl" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/visualforce_highlight_rules" { + export const VisualforceHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/visualforce" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/vue_highlight_rules" { + export const VueHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/vue" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/wollok_highlight_rules" { + export const WollokHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/wollok" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/xml_highlight_rules" { + export const XmlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/xml" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/yaml_highlight_rules" { + export const YamlHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/yaml" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/zeek_highlight_rules" { + export const ZeekHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/zeek" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} + +declare module "ace-code/src/mode/zig_highlight_rules" { + export const ZigHighlightRules: new () => import("ace-code").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/zig" { + export const Mode: new () => import("ace-code").Ace.SyntaxMode; +} \ No newline at end of file diff --git a/ace.d.ts b/ace.d.ts index def2df0e865..276d900f33c 100644 --- a/ace.d.ts +++ b/ace.d.ts @@ -1,797 +1,1070 @@ -export namespace Ace { - export type NewLineMode = 'auto' | 'unix' | 'windows'; +/* This file is generated using `npm run update-types` */ - export interface Anchor extends EventEmitter { - getPosition(): Position; - getDocument(): Document; - setPosition(row: number, column: number, noClip?: boolean): void; - detach(): void; - attach(doc: Document): void; - } - - export interface Document extends EventEmitter { - setValue(text: string): void; - getValue(): string; - createAnchor(row: number, column: number): Anchor; - getNewLineCharacter(): string; - setNewLineMode(newLineMode: NewLineMode): void; - getNewLineMode(): NewLineMode; - isNewLine(text: string): boolean; - getLine(row: number): string; - getLines(firstRow: number, lastRow: number): string[]; - getAllLines(): string[]; - getTextRange(range: Range): string; - getLinesForRange(range: Range): string[]; - insert(position: Position, text: string): Position; - insertInLine(position: Position, text: string): Position; - clippedPos(row: number, column: number): Point; - clonePos(pos: Point): Point; - pos(row: number, column: number): Point; - insertFullLines(row: number, lines: string[]): void; - insertMergedLines(position: Position, lines: string[]): Point; - remove(range: Range): Position; - removeInLine(row: number, startColumn: number, endColumn: number): Position; - removeFullLines(firstRow: number, lastRow: number): string[]; - removeNewLine(row: number): void; - replace(range: Range, text: string): Position; - applyDeltas(deltas: Delta[]): void; - revertDeltas(deltas: Delta[]): void; - applyDelta(delta: Delta, doNotValidate?: boolean): void; - revertDelta(delta: Delta): void; - indexToPosition(index: number, startRow: number): Position; - positionToIndex(pos: Position, startRow?: number): number; - } - - export interface FoldLine { - folds: Fold[]; - range: Range; - start: Point; - end: Point; - - shiftRow(shift: number): void; - addFold(fold: Fold): void; - containsRow(row: number): boolean; - walk(callback: Function, endRow?: number, endColumn?: number): void; - getNextFoldTo(row: number, column: number): null | { fold: Fold, kind: string }; - addRemoveChars(row: number, column: number, len: number): void; - split(row: number, column: number): FoldLine; - merge(foldLineNext: FoldLine): void; - idxToPosition(idx: number): Point; - } - - export interface Fold { - range: Range; - start: Point; - end: Point; - foldLine?: FoldLine; - sameRow: boolean; - subFolds: Fold[]; - - setFoldLine(foldLine: FoldLine): void; - clone(): Fold; - addSubFold(fold: Fold): Fold; - restoreRange(range: Range): void; - } - - export interface Range { - start: Point; - end: Point; - - isEqual(range: Range): boolean; - toString(): string; - contains(row: number, column: number): boolean; - compareRange(range: Range): number; - comparePoint(p: Point): number; - containsRange(range: Range): boolean; - intersects(range: Range): boolean; - isEnd(row: number, column: number): boolean; - isStart(row: number, column: number): boolean; - setStart(row: number, column: number): void; - setEnd(row: number, column: number): void; - inside(row: number, column: number): boolean; - insideStart(row: number, column: number): boolean; - insideEnd(row: number, column: number): boolean; - compare(row: number, column: number): number; - compareStart(row: number, column: number): number; - compareEnd(row: number, column: number): number; - compareInside(row: number, column: number): number; - clipRows(firstRow: number, lastRow: number): Range; - extend(row: number, column: number): Range; - isEmpty(): boolean; - isMultiLine(): boolean; - clone(): Range; - collapseRows(): Range; - toScreenRange(session: EditSession): Range; - moveBy(row: number, column: number): void; - } - - export interface EditSessionOptions { - wrap: string | number; - wrapMethod: 'code' | 'text' | 'auto'; - indentedSoftWrap: boolean; - firstLineNumber: number; - useWorker: boolean; - useSoftTabs: boolean; - tabSize: number; - navigateWithinSoftTabs: boolean; - foldStyle: 'markbegin' | 'markbeginend' | 'manual'; - overwrite: boolean; - newLineMode: NewLineMode; - mode: string; - } - - export interface VirtualRendererOptions { - animatedScroll: boolean; - showInvisibles: boolean; - showPrintMargin: boolean; - printMarginColumn: number; - printMargin: boolean | number; - showGutter: boolean; - fadeFoldWidgets: boolean; - showFoldWidgets: boolean; - showLineNumbers: boolean; - displayIndentGuides: boolean; - highlightGutterLine: boolean; - hScrollBarAlwaysVisible: boolean; - vScrollBarAlwaysVisible: boolean; - fontSize: number; - fontFamily: string; - maxLines: number; - minLines: number; - scrollPastEnd: boolean; - fixedWidthGutter: boolean; - theme: string; - hasCssTransforms: boolean; - maxPixelHeight: number; - } - - export interface MouseHandlerOptions { - scrollSpeed: number; - dragDelay: number; - dragEnabled: boolean; - focusTimeout: number; - tooltipFollowsMouse: boolean; - } - - export interface EditorOptions extends EditSessionOptions, - MouseHandlerOptions, - VirtualRendererOptions { - selectionStyle: string; - highlightActiveLine: boolean; - highlightSelectedWord: boolean; - readOnly: boolean; - copyWithEmptySelection: boolean; - cursorStyle: 'ace' | 'slim' | 'smooth' | 'wide'; - mergeUndoDeltas: true | false | 'always'; - behavioursEnabled: boolean; - wrapBehavioursEnabled: boolean; - autoScrollEditorIntoView: boolean; - keyboardHandler: string; - value: string; - session: EditSession; - } - - export interface SearchOptions { - needle: string | RegExp; - preventScroll: boolean; - backwards: boolean; - start: Range; - skipCurrent: boolean; - range: Range; - preserveCase: boolean; - regExp: RegExp; - wholeWord: string; - caseSensitive: boolean; - wrap: boolean; - } - - export interface EventEmitter { - once(name: string, callback: Function): void; - setDefaultHandler(name: string, callback: Function): void; - removeDefaultHandler(name: string, callback: Function): void; - on(name: string, callback: Function, capturing?: boolean): void; - addEventListener(name: string, callback: Function, capturing?: boolean): void; - off(name: string, callback: Function): void; - removeListener(name: string, callback: Function): void; - removeEventListener(name: string, callback: Function): void; - } - - export interface Point { - row: number; - column: number; - } - - export interface Delta { - action: 'insert' | 'remove'; - start: Point; - end: Point; - lines: string[]; - } - - export interface Annotation { - row?: number; - column?: number; - text: string; - type: string; - } - - export interface Command { - name?: string; - bindKey?: string | { mac?: string, win?: string }; - readOnly?: boolean; - exec: (editor: Editor, args?: any) => void; - } - - export type CommandLike = Command | ((editor: Editor) => void); - - export interface KeyboardHandler { - handleKeyboard: Function; - } - - export interface MarkerLike { - range: Range; - type: string; - renderer?: MarkerRenderer; - clazz: string; - inFront: boolean; - id: number; - update?: (html: string[], - // TODO maybe define Marker class - marker: any, - session: EditSession, - config: any) => void; - } - - export type MarkerRenderer = (html: string[], - range: Range, - left: number, - top: number, - config: any) => void; - - export interface Token { - type: string; - value: string; - index?: number; - start?: number; - } - - export interface Completion { - value: string; - score: number; - meta?: string; - name?: string; - caption?: string; - } - - export interface Tokenizer { - removeCapturingGroups(src: string): string; - createSplitterRegexp(src: string, flag?: string): RegExp; - getLineTokens(line: string, startState: string | string[]): Token[]; - } - - export interface SyntaxMode { - getTokenizer(): Tokenizer; - toggleCommentLines(state: any, - session: EditSession, - startRow: number, - endRow: number): void; - toggleBlockComment(state: any, - session: EditSession, - range: Range, - cursor: Position): void; - getNextLineIndent(state: any, line: string, tab: string): string; - checkOutdent(state: any, line: string, input: string): boolean; - autoOutdent(state: any, doc: Document, row: number): void; - // TODO implement WorkerClient types - createWorker(session: EditSession): any; - createModeDelegates(mapping: {[key: string]: string}): void; - transformAction(state: string, - action: string, - editor: Editor, - session: EditSession, - text: string): any; - getKeywords(append?: boolean): Array; - getCompletions(state: string, - session: EditSession, - pos: Position, - prefix: string): Completion[]; - } - - export interface Config { - get(key: string): any; - set(key: string, value: any): void; - all(): {[key: string]: any}; - moduleUrl(name: string, component?: string): string; - setModuleUrl(name: string, subst: string): string; - loadModule(moduleName: string | [string, string], - onLoad: (module: any) => void): void; - init(packaged: any): any; - defineOptions(obj: any, path: string, options: {[key: string]: any}): Config; - resetOptions(obj: any): void; - setDefaultValue(path: string, name: string, value: any): void; - setDefaultValues(path: string, optionHash: {[key: string]: any}): void; - } - - export interface OptionsProvider { - setOptions(optList: {[key: string]: any}): void; - getOptions(optionNames?: string[] | {[key: string]: any}): {[key: string]: any}; - setOption(name: string, value: any): void; - getOption(name: string): any; - } - - export interface UndoManager { - addSession(session: EditSession): void; - add(delta: Delta, allowMerge: boolean, session: EditSession): void; - addSelection(selection: string, rev?: number): void; - startNewGroup(): void; - markIgnored(from: number, to?: number): void; - getSelection(rev: number, after?: boolean): { value: string, rev: number }; - getRevision(): number; - getDeltas(from: number, to?: number): Delta[]; - undo(session: EditSession, dontSelect?: boolean): void; - redo(session: EditSession, dontSelect?: boolean): void; - reset(): void; - canUndo(): boolean; - canRedo(): boolean; - bookmark(rev?: number): void; - isAtBookmark(): boolean; - } - - export interface EditSession extends EventEmitter, OptionsProvider { - selection: Selection; - - on(name: 'changeFold', - callback: (obj: { data: Fold, action: string }) => void): void; - on(name: 'changeScrollLeft', callback: (scrollLeft: number) => void): void; - on(name: 'changeScrollTop', callback: (scrollTop: number) => void): void; - on(name: 'tokenizerUpdate', - callback: (obj: { data: { first: number, last: number } }) => void): void; - - - setOption(name: T, value: EditSessionOptions[T]): void; - getOption(name: T): EditSessionOptions[T]; - - setDocument(doc: Document): void; - getDocument(): Document; - resetCaches(): void; - setValue(text: string): void; - getValue(): string; - getSelection(): Selection; - getState(row: number): string; - getTokens(row: number): Token[]; - getTokenAt(row: number, column: number): Token | null; - setUndoManager(undoManager: UndoManager): void; - markUndoGroup(): void; - getUndoManager(): UndoManager; - getTabString(): string; - setUseSoftTabs(val: boolean): void; - getUseSoftTabs(): boolean; - setTabSize(tabSize: number): void; - getTabSize(): number; - isTabStop(position: Position): boolean; - setNavigateWithinSoftTabs(navigateWithinSoftTabs: boolean): void; - getNavigateWithinSoftTabs(): boolean; - setOverwrite(overwrite: boolean): void; - getOverwrite(): boolean; - toggleOverwrite(): void; - addGutterDecoration(row: number, className: string): void; - removeGutterDecoration(row: number, className: string): void; - getBreakpoints(): string[]; - setBreakpoints(rows: number[]): void; - clearBreakpoints(): void; - setBreakpoint(row: number, className: string): void; - clearBreakpoint(row: number): void; - addMarker(range: Range, - clazz: string, - type: MarkerRenderer, - inFront: boolean): number; - addDynamicMarker(marker: MarkerLike, inFront: boolean): MarkerLike; - removeMarker(markerId: number): void; - getMarkers(inFront?: boolean): MarkerLike[]; - highlight(re: RegExp): void; - highlightLines(startRow: number, - endRow: number, - clazz: string, - inFront?: boolean): Range; - setAnnotations(annotations: Annotation[]): void; - getAnnotations(): Annotation[]; - clearAnnotations(): void; - getWordRange(row: number, column: number): Range; - getAWordRange(row: number, column: number): Range; - setNewLineMode(newLineMode: NewLineMode): void; - getNewLineMode(): NewLineMode; - setUseWorker(useWorker: boolean): void; - getUseWorker(): boolean; - setMode(mode: string | SyntaxMode, callback?: () => void): void; - getMode(): SyntaxMode; - setScrollTop(scrollTop: number): void; - getScrollTop(): number; - setScrollLeft(scrollLeft: number): void; - getScrollLeft(): number; - getScreenWidth(): number; - getLineWidgetMaxWidth(): number; - getLine(row: number): string; - getLines(firstRow: number, lastRow: number): string[]; - getLength(): number; - getTextRange(range: Range): string; - insert(position: Position, text: string): void; - remove(range: Range): void; - removeFullLines(firstRow: number, lastRow: number): void; - undoChanges(deltas: Delta[], dontSelect?: boolean): void; - redoChanges(deltas: Delta[], dontSelect?: boolean): void; - setUndoSelect(enable: boolean): void; - replace(range: Range, text: string): void; - moveText(fromRange: Range, toPosition: Position, copy?: boolean): void; - indentRows(startRow: number, endRow: number, indentString: string): void; - outdentRows(range: Range): void; - moveLinesUp(firstRow: number, lastRow: number): void; - moveLinesDown(firstRow: number, lastRow: number): void; - duplicateLines(firstRow: number, lastRow: number): void; - setUseWrapMode(useWrapMode: boolean): void; - getUseWrapMode(): boolean; - setWrapLimitRange(min: number, max: number): void; - adjustWrapLimit(desiredLimit: number): boolean; - getWrapLimit(): number; - setWrapLimit(limit: number): void; - getWrapLimitRange(): { min: number, max: number }; - getRowLineCount(row: number): number; - getRowWrapIndent(screenRow: number): number; - getScreenLastRowColumn(screenRow: number): number; - getDocumentLastRowColumn(docRow: number, docColumn: number): number; - getdocumentLastRowColumnPosition(docRow: number, docColumn: number): Position; - getRowSplitData(row: number): string | undefined; - getScreenTabSize(screenColumn: number): number; - screenToDocumentRow(screenRow: number, screenColumn: number): number; - screenToDocumentColumn(screenRow: number, screenColumn: number): number; - screenToDocumentPosition(screenRow: number, - screenColumn: number, - offsetX?: number): Position; - documentToScreenPosition(docRow: number, docColumn: number): Position; - documentToScreenPosition(position: Position): Position; - documentToScreenColumn(row: number, docColumn: number): number; - documentToScreenRow(docRow: number, docColumn: number): number; - getScreenLength(): number; - destroy(): void; - } - - export interface KeyBinding { - setDefaultHandler(handler: KeyboardHandler): void; - setKeyboardHandler(handler: KeyboardHandler): void; - addKeyboardHandler(handler: KeyboardHandler, pos: number): void; - removeKeyboardHandler(handler: KeyboardHandler): boolean; - getKeyboardHandler(): KeyboardHandler; - getStatusText(): string; - } - - export interface CommandManager extends EventEmitter { - on(name: 'exec', callback: (obj: { - editor: Editor, - command: Command, - args: any[] - }) => void): void; - once(name: string, callback: Function): void; - setDefaultHandler(name: string, callback: Function): void; - removeDefaultHandler(name: string, callback: Function): void; - on(name: string, callback: Function, capturing?: boolean): void; - addEventListener(name: string, callback: Function, capturing?: boolean): void; - off(name: string, callback: Function): void; - removeListener(name: string, callback: Function): void; - removeEventListener(name: string, callback: Function): void; - - exec(command: string, editor: Editor, args: any): boolean; - toggleRecording(editor: Editor): void; - replay(editor: Editor): void; - addCommand(command: Command): void; - removeCommand(command: Command, keepCommand?: boolean): void; - bindKey(key: string | { mac?: string, win?: string}, - command: CommandLike, - position?: number): void; - } - - export interface VirtualRenderer extends OptionsProvider, EventEmitter { - container: HTMLElement; - - setOption(name: T, value: VirtualRendererOptions[T]): void; - getOption(name: T): VirtualRendererOptions[T]; - - setSession(session: EditSession): void; - updateLines(firstRow: number, lastRow: number, force?: boolean): void; - updateText(): void; - updateFull(force?: boolean): void; - updateFontSize(): void; - adjustWrapLimit(): boolean; - setAnimatedScroll(shouldAnimate: boolean): void; - getAnimatedScroll(): boolean; - setShowInvisibles(showInvisibles: boolean): void; - getShowInvisibles(): boolean; - setDisplayIndentGuides(display: boolean): void; - getDisplayIndentGuides(): boolean; - setShowPrintMargin(showPrintMargin: boolean): void; - getShowPrintMargin(): boolean; - setPrintMarginColumn(showPrintMargin: boolean): void; - getPrintMarginColumn(): boolean; - setShowGutter(show: boolean): void; - getShowGutter(): boolean; - setFadeFoldWidgets(show: boolean): void; - getFadeFoldWidgets(): boolean; - setHighlightGutterLine(shouldHighlight: boolean): void; - getHighlightGutterLine(): boolean; - getContainerElement(): HTMLElement; - getMouseEventTarget(): HTMLElement; - getTextAreaContainer(): HTMLElement; - getFirstVisibleRow(): number; - getFirstFullyVisibleRow(): number; - getLastFullyVisibleRow(): number; - getLastVisibleRow(): number; - setPadding(padding: number): void; - setScrollMargin(top: number, - bottom: number, - left: number, - right: number): void; - setHScrollBarAlwaysVisible(alwaysVisible: boolean): void; - getHScrollBarAlwaysVisible(): boolean; - setVScrollBarAlwaysVisible(alwaysVisible: boolean): void; - getVScrollBarAlwaysVisible(): boolean; - freeze(): void; - unfreeze(): void; - updateFrontMarkers(): void; - updateBackMarkers(): void; - updateBreakpoints(): void; - setAnnotations(annotations: Annotation[]): void; - updateCursor(): void; - hideCursor(): void; - showCursor(): void; - scrollSelectionIntoView(anchor: Position, - lead: Position, - offset?: number): void; - scrollCursorIntoView(cursor: Position, offset?: number): void; - getScrollTop(): number; - getScrollLeft(): number; - getScrollTopRow(): number; - getScrollBottomRow(): number; - scrollToRow(row: number): void; - alignCursor(cursor: Position | number, alignment: number): number; - scrollToLine(line: number, - center: boolean, - animate: boolean, - callback: () => void): void; - animateScrolling(fromValue: number, callback: () => void): void; - scrollToY(scrollTop: number): void; - scrollToX(scrollLeft: number): void; - scrollTo(x: number, y: number): void; - scrollBy(deltaX: number, deltaY: number): void; - isScrollableBy(deltaX: number, deltaY: number): boolean; - textToScreenCoordinates(row: number, column: number): { pageX: number, pageY: number}; - visualizeFocus(): void; - visualizeBlur(): void; - showComposition(position: number): void; - setCompositionText(text: string): void; - hideComposition(): void; - setTheme(theme: string, callback?: () => void): void; - getTheme(): string; - setStyle(style: string, include?: boolean): void; - unsetStyle(style: string): void; - setCursorStyle(style: string): void; - setMouseCursor(cursorStyle: string): void; - attachToShadowRoot(): void; - destroy(): void; - } - - - export interface Selection extends EventEmitter { - moveCursorWordLeft(): void; - moveCursorWordRight(): void; - fromOrientedRange(range: Range): void; - setSelectionRange(match: any): void; - getAllRanges(): Range[]; - addRange(range: Range): void; - isEmpty(): boolean; - isMultiLine(): boolean; - setCursor(row: number, column: number): void; - setAnchor(row: number, column: number): void; - getAnchor(): Position; - getCursor(): Position; - isBackwards(): boolean; - getRange(): Range; - clearSelection(): void; - selectAll(): void; - setRange(range: Range, reverse?: boolean): void; - selectTo(row: number, column: number): void; - selectToPosition(pos: any): void; - selectUp(): void; - selectDown(): void; - selectRight(): void; - selectLeft(): void; - selectLineStart(): void; - selectLineEnd(): void; - selectFileEnd(): void; - selectFileStart(): void; - selectWordRight(): void; - selectWordLeft(): void; - getWordRange(): void; - selectWord(): void; - selectAWord(): void; - selectLine(): void; - moveCursorUp(): void; - moveCursorDown(): void; - moveCursorLeft(): void; - moveCursorRight(): void; - moveCursorLineStart(): void; - moveCursorLineEnd(): void; - moveCursorFileEnd(): void; - moveCursorFileStart(): void; - moveCursorLongWordRight(): void; - moveCursorLongWordLeft(): void; - moveCursorBy(rows: number, chars: number): void; - moveCursorToPosition(position: any): void; - moveCursorTo(row: number, column: number, keepDesiredColumn?: boolean): void; - moveCursorToScreen(row: number, column: number, keepDesiredColumn: boolean): void; - } - var Selection: { - new(session: EditSession): Selection; - } - - export interface Editor extends OptionsProvider, EventEmitter { - container: HTMLElement; - renderer: VirtualRenderer; - id: string; - commands: CommandManager; - keyBinding: KeyBinding; - session: EditSession; - selection: Selection; - - on(name: 'blur', callback: (e: Event) => void): void; - on(name: 'change', callback: (delta: Delta) => void): void; - on(name: 'changeSelectionStyle', callback: (obj: { data: string }) => void): void; - on(name: 'changeSession', - callback: (obj: { session: EditSession, oldSession: EditSession }) => void): void; - on(name: 'copy', callback: (obj: { text: string }) => void): void; - on(name: 'focus', callback: (e: Event) => void): void; - on(name: 'paste', callback: (obj: { text: string }) => void): void; - - setOption(name: T, value: EditorOptions[T]): void; - getOption(name: T): EditorOptions[T]; - - setKeyboardHandler(keyboardHandler: string, callback?: () => void): void; - getKeyboardHandler(): string; - setSession(session: EditSession): void; - getSession(): EditSession; - setValue(val: string, cursorPos?: number): string; - getValue(): string; - getSelection(): Selection; - resize(force?: boolean): void; - setTheme(theme: string, callback?: () => void): void; - getTheme(): string; - setStyle(style: string): void; - unsetStyle(style: string): void; - getFontSize(): string; - setFontSize(size: string): void; - focus(): void; - isFocused(): boolean; - flur(): void; - getSelectedText(): string; - getCopyText(): string; - execCommand(command: string | string[], args: any): boolean; - insert(text: string, pasted?: boolean): void; - setOverwrite(overwrite: boolean): void; - getOverwrite(): boolean; - toggleOverwrite(): void; - setScrollSpeed(speed: number): void; - getScrollSpeed(): number; - setDragDelay(dragDelay: number): void; - getDragDelay(): number; - setSelectionStyle(val: string): void; - getSelectionStyle(): string; - setHighlightActiveLine(shouldHighlight: boolean): void; - getHighlightActiveLine(): boolean; - setHighlightGutterLine(shouldHighlight: boolean): void; - getHighlightGutterLine(): boolean; - setHighlightSelectedWord(shouldHighlight: boolean): void; - getHighlightSelectedWord(): boolean; - setAnimatedScroll(shouldAnimate: boolean): void; - getAnimatedScroll(): boolean; - setShowInvisibles(showInvisibles: boolean): void; - getShowInvisibles(): boolean; - setDisplayIndentGuides(display: boolean): void; - getDisplayIndentGuides(): boolean; - setShowPrintMargin(showPrintMargin: boolean): void; - getShowPrintMargin(): boolean; - setPrintMarginColumn(showPrintMargin: number): void; - getPrintMarginColumn(): number; - setReadOnly(readOnly: boolean): void; - getReadOnly(): boolean; - setBehavioursEnabled(enabled: boolean): void; - getBehavioursEnabled(): boolean; - setWrapBehavioursEnabled(enabled: boolean): void; - getWrapBehavioursEnabled(): boolean; - setShowFoldWidgets(show: boolean): void; - getShowFoldWidgets(): boolean; - setFadeFoldWidgets(fade: boolean): void; - getFadeFoldWidgets(): boolean; - remove(dir?: 'left' | 'right'): void; - removeWordRight(): void; - removeWordLeft(): void; - removeLineToEnd(): void; - splitLine(): void; - transposeLetters(): void; - toLowerCase(): void; - toUpperCase(): void; - indent(): void; - blockIndent(): void; - blockOutdent(): void; - sortLines(): void; - toggleCommentLines(): void; - toggleBlockComment(): void; - modifyNumber(amount: number): void; - removeLines(): void; - duplicateSelection(): void; - moveLinesDown(): void; - moveLinesUp(): void; - moveText(range: Range, toPosition: Point, copy?: boolean): Range; - copyLinesUp(): void; - copyLinesDown(): void; - getFirstVisibleRow(): number; - getLastVisibleRow(): number; - isRowVisible(row: number): boolean; - isRowFullyVisible(row: number): boolean; - selectPageDown(): void; - selectPageUp(): void; - gotoPageDown(): void; - gotoPageUp(): void; - scrollPageDown(): void; - scrollPageUp(): void; - scrollToRow(row: number): void; - scrollToLine(line: number, center: boolean, animate: boolean, callback: () => void): void; - centerSelection(): void; - getCursorPosition(): Point; - getCursorPositionScreen(): Point; - getSelectionRange(): Range; - selectAll(): void; - clearSelection(): void; - moveCursorTo(row: number, column: number): void; - moveCursorToPosition(pos: Point): void; - jumpToMatching(select: boolean, expand: boolean): void; - gotoLine(lineNumber: number, column: number, animate: boolean): void; - navigateTo(row: number, column: number): void; - navigateUp(): void; - navigateDown(): void; - navigateLeft(): void; - navigateRight(): void; - navigateLineStart(): void; - navigateLineEnd(): void; - navigateFileEnd(): void; - navigateFileStart(): void; - navigateWordRight(): void; - navigateWordLeft(): void; - replace(replacement: string, options?: Partial): number; - replaceAll(replacement: string, options?: Partial): number; - getLastSearchOptions(): Partial; - find(needle: string, options?: Partial, animate?: boolean): void; - findNext(options?: Partial, animate?: boolean): void; - findPrevious(options?: Partial, animate?: boolean): void; - undo(): void; - redo(): void; - destroy(): void; - setAutoScrollEditorIntoView(enable: boolean): void; - } +/// +/// +/// +/// +/// +/// +declare module "ace-code" { + export namespace Ace { + type Anchor = import("ace-code/src/anchor").Anchor; + type Editor = import("ace-code/src/editor").Editor; + type EditSession = import("ace-code/src/edit_session").EditSession; + type Document = import("ace-code/src/document").Document; + type Fold = import("ace-code/src/edit_session/fold").Fold; + type FoldLine = import("ace-code/src/edit_session/fold_line").FoldLine; + type Range = import("ace-code/src/range").Range; + type VirtualRenderer = import("ace-code/src/virtual_renderer").VirtualRenderer; + type UndoManager = import("ace-code/src/undomanager").UndoManager; + type Tokenizer = import("ace-code/src/tokenizer").Tokenizer; + type TokenIterator = import("ace-code/src/token_iterator").TokenIterator; + type Selection = import("ace-code/src/selection").Selection; + type Autocomplete = import("ace-code/src/autocomplete").Autocomplete; + type InlineAutocomplete = import("ace-code/src/ext/inline_autocomplete").InlineAutocomplete; + type CompletionProvider = import("ace-code/src/autocomplete").CompletionProvider; + type AcePopup = import("ace-code/src/autocomplete/popup").AcePopup; + type AceInline = import("ace-code/src/autocomplete/inline").AceInline; + type MouseEvent = import("ace-code/src/mouse/mouse_event").MouseEvent; + type RangeList = import("ace-code/src/range_list").RangeList; + type FilteredList = import("ace-code/src/autocomplete").FilteredList; + type LineWidgets = import("ace-code/src/line_widgets").LineWidgets; + type SearchBox = import("ace-code/src/ext/searchbox").SearchBox; + type Occur = import("ace-code/src/occur").Occur; + type DefaultHandlers = import("ace-code/src/mouse/default_handlers").DefaultHandlers; + type GutterHandler = import("ace-code/src/mouse/default_gutter_handler").GutterHandler; + type DragdropHandler = import("ace-code/src/mouse/dragdrop_handler").DragdropHandler; + type AppConfig = import("ace-code/src/lib/app_config").AppConfig; + type Config = typeof import("ace-code/src/config"); + type GutterTooltip = import("ace-code/src/mouse/default_gutter_handler").GutterTooltip; + type GutterKeyboardEvent = import("ace-code/src/keyboard/gutter_handler").GutterKeyboardEvent; + type HoverTooltip = import("ace-code/src/tooltip").HoverTooltip; + type Tooltip = import("ace-code/src/tooltip").Tooltip; + type TextInput = import("ace-code/src/keyboard/textinput").TextInput; + type DiffChunk = import("ace-code/src/ext/diff/base_diff_view").DiffChunk; + type AfterLoadCallback = (err: Error | null, module: unknown) => void; + type LoaderFunction = (moduleName: string, afterLoad: AfterLoadCallback) => void; + export interface ConfigOptions { + packaged: boolean; + workerPath: string | null; + modePath: string | null; + themePath: string | null; + basePath: string; + suffix: string; + loadWorkerFromBlob: boolean; + sharedPopups: boolean; + useStrictCSP: boolean | null; + } + interface Theme { + cssClass?: string; + cssText?: string; + padding?: number | string; + isDark?: boolean; + } + interface ScrollBar { + setVisible(visible: boolean): void; + [key: string]: any; + } + interface HScrollbar extends ScrollBar { + setWidth(width: number): void; + } + interface VScrollbar extends ScrollBar { + setHeight(width: number): void; + } + interface LayerConfig { + width: number; + padding: number; + firstRow: number; + firstRowScreen: number; + lastRow: number; + lineHeight: number; + characterWidth: number; + minHeight: number; + maxHeight: number; + offset: number; + height: number; + gutterOffset: number; + } + interface HardWrapOptions { + /** First row of the range to process */ + startRow: number; + /** Last row of the range to process */ + endRow: number; + /** Whether to merge short adjacent lines that fit within the limit */ + allowMerge?: boolean; + /** Maximum column width for line wrapping (defaults to editor's print margin) */ + column?: number; + } + interface CommandBarOptions { + maxElementsOnTooltip: number; + alwaysShow: boolean; + showDelay: number; + hideDelay: number; + } + interface ScreenCoordinates { + row: number; + column: number; + side?: 1 | -1; + offsetX?: number; + } + interface Folding { + /** + * Looks up a fold at a given row/column. Possible values for side: + * -1: ignore a fold if fold.start = row/column + * +1: ignore a fold if fold.end = row/column + **/ + getFoldAt(row: number, column: number, side?: number): Ace.Fold; + /** + * Returns all folds in the given range. Note, that this will return folds + **/ + getFoldsInRange(range: Ace.Range | Ace.Delta): Ace.Fold[]; + getFoldsInRangeList(ranges: Ace.Range[] | Ace.Range): Ace.Fold[]; + /** + * Returns all folds in the document + */ + getAllFolds(): Ace.Fold[]; + /** + * Returns the string between folds at the given position. + * E.g. + * foob|arwolrd -> "bar" + * foobarwol|rd -> "world" + * foobarwolrd -> + * + * where | means the position of row/column + * + * The trim option determs if the return string should be trimed according + * to the "side" passed with the trim value: + * + * E.g. + * foob|arwolrd -trim=-1> "b" + * foobarwol|rd -trim=+1> "rld" + * fo|obarwolrd -trim=00> "foo" + */ + getFoldStringAt(row: number, column: number, trim?: number, foldLine?: Ace.FoldLine): string | null; + getFoldLine(docRow: number, startFoldLine?: Ace.FoldLine): null | Ace.FoldLine; + /** + * Returns the fold which starts after or contains docRow + */ + getNextFoldLine(docRow: number, startFoldLine?: Ace.FoldLine): null | Ace.FoldLine; + getFoldedRowCount(first: number, last: number): number; + /** + * Adds a new fold. + * The new created Fold object or an existing fold object in case the + * passed in range fits an existing fold exactly. + */ + addFold(placeholder: Ace.Fold | string, range?: Ace.Range): Ace.Fold; + addFolds(folds: Ace.Fold[]): void; + removeFold(fold: Ace.Fold): void; + removeFolds(folds: Ace.Fold[]): void; + expandFold(fold: Ace.Fold): void; + expandFolds(folds: Ace.Fold[]): void; + unfold(location?: number | null | Ace.Point | Ace.Range | Ace.Range[], expandInner?: boolean): Ace.Fold[] | undefined; + /** + * Checks if a given documentRow is folded. This is true if there are some + * folded parts such that some parts of the line is still visible. + **/ + isRowFolded(docRow: number, startFoldRow?: Ace.FoldLine): boolean; + getRowFoldEnd(docRow: number, startFoldRow?: Ace.FoldLine): number; + getRowFoldStart(docRow: number, startFoldRow?: Ace.FoldLine): number; + getFoldDisplayLine(foldLine: Ace.FoldLine, endRow?: number | null, endColumn?: number | null, startRow?: number | null, startColumn?: number | null): string; + getDisplayLine(row: number, endColumn: number | null, startRow: number | null, startColumn: number | null): string; + toggleFold(tryToUnfold?: boolean): void; + getCommentFoldRange(row: number, column: number, dir?: number): Ace.Range | undefined; + foldAll(startRow?: number | null, endRow?: number | null, depth?: number | null, test?: Function): void; + foldToLevel(level: number): void; + foldAllComments(): void; + setFoldStyle(style: string): void; + foldWidgets: any[]; + getFoldWidget: any; + getFoldWidgetRange: any; + getParentFoldRangeData(row: number, ignoreCurrent?: boolean): { + range?: Ace.Range; + firstRange?: Ace.Range; + }; + onFoldWidgetClick(row: number, e: any): void; + toggleFoldWidget(toggleParent?: boolean): void; + updateFoldWidgets(delta: Ace.Delta): void; + tokenizerUpdateFoldWidgets(e: any): void; + } + interface BracketMatch { + findMatchingBracket: (position: Point, chr?: string) => Point; + getBracketRange: (pos: Point) => null | Range; + /** + * Returns: + * * null if there is no any bracket at `pos`; + * * two Ranges if there is opening and closing brackets; + * * one Range if there is only one bracket + */ + getMatchingBracketRanges: (pos: Point, isBackwards?: boolean) => null | Range[]; + /** + * Returns [[Range]]'s for matching tags and tag names, if there are any + */ + getMatchingTags: (pos: Point) => { + closeTag: Range; + closeTagName: Range; + openTag: Range; + openTagName: Range; + }; + } + interface IRange { + start: Point; + end: Point; + } + interface LineWidget { + editor?: Editor; + el?: HTMLElement; + rowCount?: number; + hidden?: boolean; + column?: number; + row: number; + session?: EditSession; + html?: string; + text?: string; + className?: string; + coverGutter?: boolean; + pixelHeight?: number; + type?: any; + destroy?: () => void; + coverLine?: boolean; + fixedWidth?: boolean; + fullWidth?: boolean; + screenWidth?: number; + rowsAbove?: number; + lenses?: CodeLenseCommand[]; + } + type NewLineMode = "auto" | "unix" | "windows"; + interface EditSessionOptions { + wrap: "off" | "free" | "printmargin" | boolean | number; + wrapMethod: "code" | "text" | "auto"; + indentedSoftWrap: boolean; + firstLineNumber: number; + useWorker: boolean; + useSoftTabs: boolean; + tabSize: number; + navigateWithinSoftTabs: boolean; + foldStyle: "markbegin" | "markbeginend" | "manual"; + overwrite: boolean; + newLineMode: NewLineMode; + mode: string; + } + interface VirtualRendererOptions { + animatedScroll: boolean; + showInvisibles: boolean; + showPrintMargin: boolean; + printMarginColumn: number; + printMargin: boolean | number; + showGutter: boolean; + fadeFoldWidgets: boolean; + showFoldWidgets: boolean; + showLineNumbers: boolean; + displayIndentGuides: boolean; + highlightIndentGuides: boolean; + highlightGutterLine: boolean; + hScrollBarAlwaysVisible: boolean; + vScrollBarAlwaysVisible: boolean; + fontSize: string | number; + fontFamily: string; + maxLines: number; + minLines: number; + scrollPastEnd: number; + fixedWidthGutter: boolean; + customScrollbar: boolean; + theme: string; + hasCssTransforms: boolean; + maxPixelHeight: number; + useSvgGutterIcons: boolean; + showFoldedAnnotations: boolean; + useResizeObserver: boolean; + } + interface MouseHandlerOptions { + scrollSpeed: number; + dragDelay: number; + dragEnabled: boolean; + focusTimeout: number; + } + interface EditorOptions extends EditSessionOptions, MouseHandlerOptions, VirtualRendererOptions { + selectionStyle: "fullLine" | "screenLine" | "text" | "line"; + highlightActiveLine: boolean; + highlightSelectedWord: boolean; + readOnly: boolean; + copyWithEmptySelection: boolean; + cursorStyle: "ace" | "slim" | "smooth" | "wide"; + mergeUndoDeltas: true | false | "always"; + behavioursEnabled: boolean; + wrapBehavioursEnabled: boolean; + enableAutoIndent: boolean; + enableBasicAutocompletion: boolean | Completer[]; + enableLiveAutocompletion: boolean | Completer[]; + liveAutocompletionDelay: number; + liveAutocompletionThreshold: number; + enableSnippets: boolean; + autoScrollEditorIntoView: boolean; + keyboardHandler: string | null; + placeholder: string; + value: string; + session: EditSession; + relativeLineNumbers: boolean; + enableMultiselect: boolean; + enableKeyboardAccessibility: boolean; + enableCodeLens: boolean; + textInputAriaLabel: string; + enableMobileMenu: boolean; + } + interface EventsBase { + [key: string]: any; + } + interface EditSessionEvents { + /** + * Emitted when the document changes. + */ + "change": (delta: Delta, emitter: EditSession) => void; + /** + * Emitted when the tab size changes, via [[EditSession.setTabSize]]. + */ + "changeTabSize": (e: undefined, emitter: EditSession) => void; + /** + * Emitted when the ability to overwrite text changes, via [[EditSession.setOverwrite]]. + */ + "changeOverwrite": (overwrite: boolean, emitter: EditSession) => void; + /** + * Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change. + */ + "changeBreakpoint": (e: { + row?: number; + breakpoint?: boolean; + }, emitter: EditSession) => void; + /** + * Emitted when a front marker changes. + */ + "changeFrontMarker": (e: undefined, emitter: EditSession) => void; + /** + * Emitted when a back marker changes. + */ + "changeBackMarker": (e: undefined, emitter: EditSession) => void; + /** + * Emitted when an annotation changes, like through [[EditSession.setAnnotations]]. + */ + "changeAnnotation": (e: {}, emitter: EditSession) => void; + /** + * Emitted when a background tokenizer asynchronously processes new rows. + */ + "tokenizerUpdate": (e: { + data: { + first: number; + last: number; + }; + }, emitter: EditSession) => void; + /** + * Emitted when the current mode changes. + */ + "changeMode": (e: any, emitter: EditSession) => void; + /** + * Emitted when the wrap mode changes. + */ + "changeWrapMode": (e: any, emitter: EditSession) => void; + /** + * Emitted when the wrapping limit changes. + */ + "changeWrapLimit": (e: any, emitter: EditSession) => void; + /** + * Emitted when a code fold is added or removed. + */ + "changeFold": (e: any, emitter: EditSession) => void; + /** + * Emitted when the scroll top changes. + * @param scrollTop The new scroll top value + **/ + "changeScrollTop": (scrollTop: number, emitter: EditSession) => void; + /** + * Emitted when the scroll left changes. + * @param scrollLeft The new scroll left value + **/ + "changeScrollLeft": (scrollLeft: number, emitter: EditSession) => void; + "changeEditor": (e: { + editor?: Editor; + oldEditor?: Editor; + }, emitter: EditSession) => void; + "changeSelection": (e: undefined, emitter: EditSession) => void; + "startOperation": (op: { + command?: { + name?: string; + }; + args?: any; + }, emitter: EditSession) => void; + "endOperation": (op: any, emitter: EditSession) => void; + "beforeEndOperation": (e: undefined, emitter: EditSession) => void; + } + interface EditorEvents { + "change": (delta: Delta, emitter: Editor) => void; + "changeSelection": (e: undefined, emitter: Editor) => void; + "input": (e: undefined, emitter: Editor) => void; + /** + * Emitted whenever the [[EditSession]] changes. + * @param e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s. + **/ + "changeSession": (e: { + oldSession: EditSession; + session: EditSession; + }, emitter: Editor) => void; + "blur": (e: any, emitter: Editor) => void; + "mousedown": (e: MouseEvent, emitter: Editor) => void; + "mousemove": (e: MouseEvent & { + scrollTop?: any; + }, emitter: Editor) => void; + "changeStatus": (e: any, emitter: Editor) => void; + "keyboardActivity": (e: any, emitter: Editor) => void; + "mousewheel": (e: MouseEvent, emitter: Editor) => void; + "mouseup": (e: MouseEvent, emitter: Editor) => void; + "beforeEndOperation": (e: any, emitter: Editor) => void; + "nativecontextmenu": (e: any, emitter: Editor) => void; + "destroy": (e: any, emitter: Editor) => void; + "focus": (e: any, emitter: Editor) => void; + /** + * Emitted when text is copied. + * @param text The copied text + **/ + "copy": (e: { + text: string; + }, emitter: Editor) => void; + /** + * Emitted when text is pasted. + **/ + "paste": (e: { + text: string; + event?: ClipboardEvent; + }, emitter: Editor) => void; + /** + * Emitted when the selection style changes, via [[Editor.setSelectionStyle]]. + * @param data Contains one property, `data`, which indicates the new selection style + **/ + "changeSelectionStyle": (data: "fullLine" | "screenLine" | "text" | "line", emitter: Editor) => void; + "changeMode": (e: { + mode?: Ace.SyntaxMode; + oldMode?: Ace.SyntaxMode; + }, emitter: Editor) => void; + //from searchbox extension + "findSearchBox": (e: { + match: boolean; + }, emitter: Editor) => void; + //from code_lens extension + "codeLensClick": (e: any, emitter: Editor) => void; + "select": (e: undefined, emitter: Editor) => void; + "gutterkeydown": (e: GutterKeyboardEvent, emitter: Editor) => void; + "gutterclick": (e: MouseEvent, emitter: Editor) => void; + "showGutterTooltip": (e: GutterTooltip, emitter: Editor) => void; + "hideGutterTooltip": (e: GutterTooltip, emitter: Editor) => void; + "compositionStart": (e: undefined, emitter: Editor) => void; + } + interface AcePopupEvents { + "click": (e: MouseEvent, emitter: AcePopup) => void; + "dblclick": (e: MouseEvent, emitter: AcePopup) => void; + "tripleclick": (e: MouseEvent, emitter: AcePopup) => void; + "quadclick": (e: MouseEvent, emitter: AcePopup) => void; + "show": (e: undefined, emitter: AcePopup) => void; + "hide": (e: undefined, emitter: AcePopup) => void; + "select": (hide: boolean, emitter: AcePopup) => void; + "changeHoverMarker": (e: any, emitter: AcePopup) => void; + } + interface DocumentEvents { + /** + * Fires whenever the document changes. + * Several methods trigger different `"change"` events. Below is a list of each action type, followed by each property that's also available: + * * `"insert"` + * * `range`: the [[Range]] of the change within the document + * * `lines`: the lines being added + * * `"remove"` + * * `range`: the [[Range]] of the change within the document + * * `lines`: the lines being removed + * + **/ + "change": (e: Delta, emitter: Document) => void; + "changeNewLineMode": (e: undefined, emitter: Document) => void; + } + interface AnchorEvents { + /** + * Fires whenever the anchor position changes. + * Both of these objects have a `row` and `column` property corresponding to the position. + * Events that can trigger this function include [[Anchor.setPosition `setPosition()`]]. + * @param {Object} e An object containing information about the anchor position. It has two properties: + * - `old`: An object describing the old Anchor position + * - `value`: An object describing the new Anchor position + **/ + "change": (e: { + old: Point; + value: Point; + }, emitter: Anchor) => void; + } + interface BackgroundTokenizerEvents { + /** + * Fires whenever the background tokeniziers between a range of rows are going to be updated. + * @param e An object containing two properties, `first` and `last`, which indicate the rows of the region being updated. + **/ + "update": (e: { + data: { + first: number; + last: number; + }; + }, emitter: import("ace-code/src/background_tokenizer").BackgroundTokenizer) => void; + } + interface SelectionEvents { + /** + * Emitted when the cursor position changes. + **/ + "changeCursor": (e: undefined, emitter: Selection) => void; + /** + * Emitted when the cursor selection changes. + **/ + "changeSelection": (e: undefined, emitter: Selection) => void; + } + interface MultiSelectionEvents extends SelectionEvents { + "multiSelect": (e: undefined, emitter: Selection) => void; + "addRange": (e: { + range: Range; + }, emitter: Selection) => void; + "removeRange": (e: { + ranges: Range[]; + }, emitter: Selection) => void; + "singleSelect": (e: undefined, emitter: Selection) => void; + } + interface PlaceHolderEvents { + "cursorEnter": (e: any, emitter: import("ace-code/src/placeholder").PlaceHolder) => void; + "cursorLeave": (e: any, emitter: import("ace-code/src/placeholder").PlaceHolder) => void; + } + interface GutterEvents { + "changeGutterWidth": (width: number, emitter: import("ace-code/src/layer/gutter").Gutter) => void; + "afterRender": (e: undefined, emitter: import("ace-code/src/layer/gutter").Gutter) => void; + } + interface TextEvents { + "changeCharacterSize": (e: any, emitter: import("ace-code/src/layer/text").Text) => void; + } + interface VirtualRendererEvents { + "afterRender": (e: any, emitter: VirtualRenderer) => void; + "beforeRender": (e: any, emitter: VirtualRenderer) => void; + "themeLoaded": (e: { + theme: string | Theme; + }, emitter: VirtualRenderer) => void; + "themeChange": (e: { + theme: string | Theme; + }, emitter: VirtualRenderer) => void; + "scrollbarVisibilityChanged": (e: undefined, emitter: VirtualRenderer) => void; + "changeCharacterSize": (e: any, emitter: VirtualRenderer) => void; + "resize": (e: any, emitter: VirtualRenderer) => void; + "autosize": (e: undefined, emitter: VirtualRenderer) => void; + } + type EmitParameters any> = T extends (first: infer First, ...rest: any[]) => any ? [ + First + ] : [ + ]; + export class EventEmitter any; + }> { + once(name: K, callback: T[K]): void; + setDefaultHandler(name: string, callback: Function): void; + removeDefaultHandler(name: string, callback: Function): void; + on(name: K, callback: T[K], capturing?: boolean): T[K]; + addEventListener(name: K, callback: T[K], capturing?: boolean): T[K]; + off(name: K, callback: T[K]): void; + removeListener(name: K, callback: T[K]): void; + removeEventListener(name: K, callback: T[K]): void; + removeAllListeners(name?: string): void; + } + interface SearchOptions { + /**The string or regular expression you're looking for*/ + needle: string | RegExp; + preventScroll: boolean; + /**Whether to search backwards from where cursor currently is*/ + backwards: boolean; + /**The starting [[Range]] or cursor position to begin the search*/ + start: Range; + /**Whether or not to include the current line in the search*/ + skipCurrent: boolean; + /**The [[Range]] to search within. Set this to `null` for the whole document*/ + range: Range | null; + preserveCase: boolean; + /**Whether the search is a regular expression or not*/ + regExp: boolean; + /**Whether the search matches only on whole words*/ + wholeWord: boolean; + /**Whether the search ought to be case-sensitive*/ + caseSensitive: boolean; + /**Whether to wrap the search back to the beginning when it hits the end*/ + wrap: boolean; + re: any; + } + interface Point { + row: number; + column: number; + } + type Position = Point; + interface Delta { + action: "insert" | "remove"; + start: Point; + end: Point; + lines: string[]; + id?: number; + folds?: Fold[]; + } + interface Annotation { + row: number; + column: number; + text: string; + type: string; + } + export interface MarkerGroupItem { + range: Range; + className: string; + } + type MarkerGroup = import("ace-code/src/marker_group").MarkerGroup; + export interface Command { + name?: string; + bindKey?: string | { + mac?: string; + win?: string; + }; + readOnly?: boolean; + exec?: (editor?: Editor | any, args?: any) => void; + isAvailable?: (editor: Editor) => boolean; + description?: string; + multiSelectAction?: "forEach" | "forEachLine" | Function; + scrollIntoView?: true | "cursor" | "center" | "selectionPart" | "animate" | "selection" | "none"; + aceCommandGroup?: string; + passEvent?: boolean; + level?: number; + action?: string; + } + type CommandLike = Command | ((editor: Editor) => void) | ((sb: SearchBox) => void); + type KeyboardHandler = Partial & { + attach?: (editor: Editor) => void; + detach?: (editor: Editor) => void; + getStatusText?: (editor?: any, data?: any) => string; + }; + export interface MarkerLike { + range?: Range; + type: string; + renderer?: MarkerRenderer; + clazz: string; + inFront?: boolean; + id?: number; + update?: (html: string[], + // TODO maybe define Marker class + marker: any, session: EditSession, config: any) => void; + [key: string]: any; + } + type MarkerRenderer = (html: string[], range: Range, left: number, top: number, config: any) => void; + interface Token { + type: string; + value: string; + index?: number; + start?: number; + } + type BaseCompletion = import("ace-code/src/autocomplete").BaseCompletion; + type SnippetCompletion = import("ace-code/src/autocomplete").SnippetCompletion; + type ValueCompletion = import("ace-code/src/autocomplete").ValueCompletion; + type Completion = import("ace-code/src/autocomplete").Completion; + type HighlightRule = ({ + defaultToken: string; + } | { + include: string; + } | { + todo: string; + } | { + token: string | string[] | ((value: string) => string); + regex: string | RegExp; + next?: string | (() => void); + push?: string; + comment?: string; + caseInsensitive?: boolean; + nextState?: string; + }) & { + [key: string]: any; + }; + type HighlightRulesMap = Record; + type KeywordMapper = (keyword: string) => string; + interface HighlightRules { + addRules(rules: HighlightRulesMap, prefix?: string): void; + getRules(): HighlightRulesMap; + embedRules(rules: (new () => HighlightRules) | HighlightRulesMap, prefix: string, escapeRules?: boolean, append?: boolean): void; + getEmbeds(): string[]; + normalizeRules(): void; + createKeywordMapper(map: Record, defaultToken?: string, ignoreCase?: boolean, splitChar?: string): KeywordMapper; + } + type FoldWidget = "start" | "end" | ""; + interface FoldMode { + foldingStartMarker: RegExp; + foldingStopMarker?: RegExp; + getFoldWidget(session: EditSession, foldStyle: string, row: number): FoldWidget; + getFoldWidgetRange(session: EditSession, foldStyle: string, row: number): Range | undefined; + indentationBlock(session: EditSession, row: number, column?: number): Range | undefined; + openingBracketBlock(session: EditSession, bracket: string, row: number, column: number, typeRe?: RegExp): Range | undefined; + closingBracketBlock(session: EditSession, bracket: string, row: number, column: number, typeRe?: RegExp): Range | undefined; + } + type BehaviorAction = (state: string | string[], action: string, editor: Editor, session: EditSession, text: string | Range) => ({ + text: string; + selection: number[]; + } | Range) & { + [key: string]: any; + } | undefined; + type BehaviorMap = Record>; + interface Behaviour { + add(name: string, action: string, callback: BehaviorAction): void; + addBehaviours(behaviours: BehaviorMap): void; + remove(name: string): void; + inherit(mode: SyntaxMode | (new () => SyntaxMode), filter: string[]): void; + getBehaviours(filter?: string[]): BehaviorMap; + } + interface Outdent { + checkOutdent(line: string, input: string): boolean; + autoOutdent(doc: Document, row: number): number | undefined; + } + interface SyntaxMode { + HighlightRules: { + new(config?: any): HighlightRules; + }; //TODO: fix this + foldingRules?: FoldMode; + /** + * characters that indicate the start of a line comment + */ + lineCommentStart?: string; + /** + * characters that indicate the start and end of a block comment + */ + blockComment?: { + start: string; + end: string; + }; + tokenRe?: RegExp; + nonTokenRe?: RegExp; + completionKeywords: string[]; + transformAction: BehaviorAction; + path?: string; + getTokenizer(): Tokenizer; + toggleCommentLines(state: string | string[], session: EditSession, startRow: number, endRow: number): void; + toggleBlockComment(state: string | string[], session: EditSession, range: Range, cursor: Point): void; + getNextLineIndent(state: string | string[], line: string, tab: string): string; + checkOutdent(state: string | string[], line: string, input: string): boolean; + autoOutdent(state: string | string[], doc: EditSession, row: number): void; + // TODO implement WorkerClient types + createWorker(session: EditSession): any; + createModeDelegates(mapping: { + [key: string]: string; + }): void; + getKeywords(append?: boolean): Array; + getCompletions(state: string | string[], session: EditSession, pos: Point, prefix: string): Completion[]; + } + interface OptionsBase { + [key: string]: any; + } + class OptionsProvider { + setOptions(optList: Partial): void; + getOptions(optionNames?: Array | Partial): Partial; + setOption(name: K, value: T[K]): void; + getOption(name: K): T[K]; + } + type KeyBinding = import("ace-code/src/keyboard/keybinding").KeyBinding; + interface CommandMap { + [name: string]: Command; + } + type execEventHandler = (obj: { + editor: Editor; + command: Command; + args: any[]; + }, emitter: CommandManager) => void; + interface CommandManagerEvents { + "exec": execEventHandler; + "afterExec": execEventHandler; + "commandUnavailable": execEventHandler; + } + type CommandManager = import("ace-code/src/commands/command_manager").CommandManager; + interface SavedSelection { + start: Point; + end: Point; + isBackwards: boolean; + } + var Selection: { + new(session: EditSession): Selection; + }; + type CompleterCallback = (error: any, completions: Completion[]) => void; + interface Completer { + /** Regular expressions defining valid identifier characters for completion triggers */ + identifierRegexps?: Array; + /** Main completion method that provides suggestions for the given context */ + getCompletions(editor: Editor, session: EditSession, position: Point, prefix: string, callback: CompleterCallback): void; + /** Returns documentation tooltip for a completion item */ + getDocTooltip?(item: Completion): void | string | Completion; + /** Called when a completion item becomes visible */ + onSeen?: (editor: Ace.Editor, completion: Completion) => void; + /** Called when a completion item is inserted */ + onInsert?: (editor: Ace.Editor, completion: Completion) => void; + /** Cleanup method called when completion is cancelled */ + cancel?(): void; + /** Unique identifier for this completer */ + id?: string; + /** Characters that trigger autocompletion when typed */ + triggerCharacters?: string[]; + /** Whether to hide inline preview text */ + hideInlinePreview?: boolean; + /** Custom insertion handler for completion items */ + insertMatch?: (editor: Editor, data: Completion) => void; + } + interface CompletionOptions { + matches?: Completion[]; + } + type CompletionProviderOptions = { + exactMatch?: boolean; + ignoreCaption?: boolean; + }; + type GatherCompletionRecord = { + prefix: string; + matches: Completion[]; + finished: boolean; + }; + type CompletionCallbackFunction = (err: Error | undefined, data: GatherCompletionRecord) => void; + type CompletionProviderCallback = (this: import("ace-code/src/autocomplete").Autocomplete, err: Error | undefined, completions: import("ace-code/src/autocomplete").FilteredList, finished: boolean) => void; + type AcePopupNavigation = "up" | "down" | "start" | "end"; + interface EditorMultiSelectProperties { + inMultiSelectMode?: boolean; + /** + * Updates the cursor and marker layers. + **/ + updateSelectionMarkers: () => void; + /** + * Adds the selection and cursor. + * @param orientedRange A range containing a cursor + **/ + addSelectionMarker: (orientedRange: Ace.Range & { + marker?: any; + }) => Ace.Range & { + marker?: any; + }; + /** + * Removes the selection marker. + * @param range The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]]. + **/ + removeSelectionMarker: (range: Ace.Range & { + marker?: any; + }) => void; + removeSelectionMarkers: (ranges: (Ace.Range & { + marker?: any; + })[]) => void; + /** + * Executes a command for each selection range. + * @param cmd The command to execute + * @param [args] Any arguments for the command + **/ + forEachSelection: (cmd: Object, args?: string, options?: Object) => void; + /** + * Removes all the selections except the last added one. + **/ + exitMultiSelectMode: () => void; + getSelectedText: () => string; + /** + * Finds and selects all the occurrences of `needle`. + * @param needle The text to find + * @param options The search options + * @param additive keeps + * @returns {Number} The cumulative count of all found matches + **/ + findAll: (needle?: string, options?: Partial, additive?: boolean) => number; + /** + * Adds a cursor above or below the active cursor. + * @param dir The direction of lines to select: -1 for up, 1 for down + * @param [skip] If `true`, removes the active selection range + */ + selectMoreLines: (dir: number, skip?: boolean) => void; + /** + * Transposes the selected ranges. + * @param {Number} dir The direction to rotate selections + **/ + transposeSelections: (dir: number) => void; + /** + * Finds the next occurrence of text in an active selection and adds it to the selections. + * @param {Number} dir The direction of lines to select: -1 for up, 1 for down + * @param {Boolean} [skip] If `true`, removes the active selection range + **/ + selectMore: (dir: number, skip?: boolean, stopAtFirst?: boolean) => void; + /** + * Aligns the cursors or selected text. + **/ + alignCursors: () => void; + multiSelect?: any; + } + /** + * Provider interface for code lens functionality + */ + interface CodeLenseProvider { + /** + * Compute code lenses for the given edit session + * @param session The edit session to provide code lenses for + * @param callback Callback function that receives errors and code lenses + */ + provideCodeLenses: (session: EditSession, callback: (err: any, payload: CodeLense[]) => void) => void; + } + /** + * Represents a command associated with a code lens + */ + interface CodeLenseCommand { + /** + * Command identifier that will be executed + */ + id?: string; + /** + * Display title for the code lens + */ + title: string; + /** + * Argument(s) to pass to the command when executed + */ + arguments?: any; + } + /** + * Represents a code lens - an actionable UI element displayed above a code line + */ + interface CodeLense { + /** + * Starting position where the code lens should be displayed + */ + start: Point; + /** + * Command to execute when the code lens is activated + */ + command?: CodeLenseCommand; + } + interface CodeLenseEditorExtension { + codeLensProviders?: CodeLenseProvider[]; + } + interface ElasticTabstopsEditorExtension { + elasticTabstops?: import("ace-code/src/ext/elastic_tabstops_lite").ElasticTabstopsLite; + } + interface TextareaEditorExtension { + setDisplaySettings?: (settings: any) => void; + } + interface PromptEditorExtension { + cmdLine?: Editor; + } + interface OptionsEditorExtension { + } + interface MultiSelectProperties { + ranges: Ace.Range[] | null; + rangeList: Ace.RangeList | null; + /** + * Adds a range to a selection by entering multiselect mode, if necessary. + * @param {Ace.Range} range The new range to add + * @param {Boolean} [$blockChangeEvents] Whether or not to block changing events + **/ + addRange(range: Ace.Range, $blockChangeEvents?: boolean): any; + inMultiSelectMode: boolean; + toSingleRange(range?: Ace.Range): void; + /** + * Removes a Range containing pos (if it exists). + * @param {Ace.Point} pos The position to remove, as a `{row, column}` object + **/ + substractPoint(pos: Ace.Point): any; + /** + * Merges overlapping ranges ensuring consistency after changes + **/ + mergeOverlappingRanges(): void; + rangeCount: number; + /** + * Returns a concatenation of all the ranges. + **/ + getAllRanges(): Ace.Range[]; + /** + * Splits all the ranges into lines. + **/ + splitIntoLines(): void; + joinSelections(): void; + toggleBlockSelection(): void; + /** + * + * Gets list of ranges composing rectangular block on the screen + * + * @param {Ace.ScreenCoordinates} screenCursor The cursor to use + * @param {Ace.ScreenCoordinates} screenAnchor The anchor to use + * @param {Boolean} [includeEmptyLines] If true, this includes ranges inside the block which are empty due to clipping + **/ + rectangularRangeBlock(screenCursor: Ace.ScreenCoordinates, screenAnchor: Ace.ScreenCoordinates, includeEmptyLines?: boolean): Ace.Range[]; + index?: number; + } + type AcePopupEventsCombined = Ace.EditorEvents & Ace.AcePopupEvents; + type AcePopupWithEditor = Ace.EventEmitter & Ace.Editor; + type InlineAutocompleteAction = "prev" | "next" | "first" | "last"; + type TooltipCommandFunction = (editor: Ace.Editor) => T; + export interface TooltipCommand extends Ace.Command { + enabled?: TooltipCommandFunction | boolean; + getValue?: TooltipCommandFunction; + type: "button" | "text" | "checkbox"; + iconCssClass?: string; + cssClass?: string; + } + export type CommandBarTooltip = import("ace-code/src/ext/command_bar").CommandBarTooltip; + export type TokenizeResult = Array>; + export interface StaticHighlightOptions { + /** Syntax mode (e.g., 'ace/mode/javascript'). Auto-detected from CSS class if not provided */ + mode?: string | SyntaxMode; + /** Color theme (e.g., 'ace/theme/textmate'). Defaults to 'ace/theme/textmate' */ + theme?: string | Theme; + /** Whether to trim whitespace from code content */ + trim?: boolean; + /** Starting line number for display */ + firstLineNumber?: number; + /** Whether to show line numbers gutter */ + showGutter?: boolean; + } + export interface Operation { + command: { + name?: string; + }; + args: any; + selectionBefore?: Range | Range[]; + selectionAfter?: Range | Range[]; + docChanged?: boolean; + selectionChanged?: boolean; + } + export interface CommandBarEvents { + "hide": (e: undefined, emitter: import("ace-code/src/ext/command_bar").CommandBarTooltip) => void; + "show": (e: undefined, emitter: import("ace-code/src/ext/command_bar").CommandBarTooltip) => void; + "alwaysShow": (e: boolean, emitter: import("ace-code/src/ext/command_bar").CommandBarTooltip) => void; + } + export interface FontMetricsEvents { + "changeCharacterSize": (e: { + data: { + height: number; + width: number; + }; + }, emitter: import("ace-code/src/layer/font_metrics").FontMetrics) => void; + } + export interface OptionPanelEvents { + "setOption": (e: { + name: string; + value: any; + }, emitter: import("ace-code/src/ext/options").OptionPanel) => void; + } + export interface ScrollbarEvents { + "scroll": (e: { + data: number; + }, emitter: ScrollBar) => void; + } + export interface TextInputAriaOptions { + activeDescendant?: string; + role?: string; + setLabel?: boolean; + inline?: boolean; + } + } + export const config: typeof import("ace-code/src/config"); + export function edit(el?: string | (HTMLElement & { + env?: any; + value?: any; + }) | null, options?: Partial): Editor; + export function createEditSession(text: import("ace-code/src/document").Document | string, mode?: import("ace-code").Ace.SyntaxMode): EditSession; + import { Editor } from "ace-code/src/editor"; + import { EditSession } from "ace-code/src/edit_session"; + import { Range } from "ace-code/src/range"; + import { UndoManager } from "ace-code/src/undomanager"; + import { VirtualRenderer as Renderer } from "ace-code/src/virtual_renderer"; + export var version: "1.43.4"; + export { Range, Editor, EditSession, UndoManager, Renderer as VirtualRenderer }; } - -export const version: string; -export const config: Ace.Config; -export function require(name: string): any; -export function edit(el: Element | string, options?: Partial): Ace.Editor; -export function createEditSession(text: Ace.Document | string, mode: Ace.SyntaxMode): Ace.EditSession; -export const VirtualRenderer: { - new(container: HTMLElement, theme?: string): Ace.VirtualRenderer; -}; -export const EditSession: { - new(text: string | Document, mode?: Ace.SyntaxMode): Ace.EditSession; -}; -export const UndoManager: { - new(): Ace.UndoManager; -}; -export const Range: { - new(startRow: number, startColumn: number, endRow: number, endColumn: number): Ace.Range; - fromPoints(start: Ace.Point, end: Ace.Point): Ace.Range; - comparePoints(p1: Ace.Point, p2: Ace.Point): number; -}; diff --git a/amplify.yml b/amplify.yml new file mode 100644 index 00000000000..0ffa5709bac --- /dev/null +++ b/amplify.yml @@ -0,0 +1,18 @@ +version: 0.1 +frontend: + phases: + preBuild: + commands: + - npm install + # IMPORTANT - Please verify your build commands + build: + commands: + - make build + artifacts: + # IMPORTANT - Please verify your build output directory + baseDirectory: / + files: + - '**/*' + cache: + paths: + - node_modules/**/* diff --git a/api/ace.html b/api/ace.html deleted file mode 100644 index e242d60c08a..00000000000 --- a/api/ace.html +++ /dev/null @@ -1,149 +0,0 @@ - -
-
-
-
-
-

Ace -

- -
-
-
-
-

The main class required to set up an Ace instance in the browser.

- -
-
-
-

Methods

-
-
-
-
- -
-
-

Creates a new EditSession, and returns the associated Document.

- -
-

Creates a new EditSession, and returns the associated Document.

- -

Arguments

textDocument | String

Required. If text is a Document, it associates the EditSession with it. Otherwise, a new Document is created, with the initial text

-
modeTextMode

Required. The initial language mode to use for the document

-
-
-
-
-
-
-
-
-
-
- -
-
-

Embeds the Ace editor into the DOM, at the element provided by el.

- -
-

Embeds the Ace editor into the DOM, at the element provided by el.

- -

Arguments

elString | DOMElement

Required. Either the id of an element, or the element itself

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Provides access to require in packed noconflict mode

- -
-

Provides access to require in packed noconflict mode

- -

Arguments

moduleNameString

Required.

-
-
-
-
-
-
-
- - - - - -
-
diff --git a/api/anchor.html b/api/anchor.html deleted file mode 100644 index 727c1cb8ba4..00000000000 --- a/api/anchor.html +++ /dev/null @@ -1,272 +0,0 @@ - -
-
-
-
-
-

Anchor -

- -
-
-
-
-

Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated.

- -
-
-
-

Constructors

-
-
-
-
- -
-
-

Creates a new Anchor and associates it with a document.

- -
-

Creates a new Anchor and associates it with a document.

- -

Arguments

docDocument

Required. The document to associate with the anchor

-
rowNumber

Required. The starting row position

-
columnNumber

Required. The starting column position

-
-
-
-
-
-
-

Events

-
-
-
-
-
    -
  • -
      -
    • Anchor.on("change", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Fires whenever the anchor position changes.

- -
-

Fires whenever the anchor position changes.

-

Both of these objects have a row and column property corresponding to the position.

-

Events that can trigger this function include setPosition().

- -

Arguments

eObject

Required. An object containing information about the anchor position. It has two properties:

-
    -
  • old: An object describing the old Anchor position
  • -
  • value: An object describing the new Anchor position
  • -
-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • Anchor.detach()
    • -
    -
      -
    -
  • -
-
-
-

When called, the 'change' event listener is removed.

- -
-

When called, the 'change' event listener is removed.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Anchor.getDocument() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current document.

- -
-

Returns the current document.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Anchor.getPosition() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns an object identifying the row and column position of the current anchor.

- -
-

Returns an object identifying the row and column position of the current anchor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Anchor.onChange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-

Sets the anchor position to the specified row and column. If noClip is true, the position is not clipped.

- -
-

Sets the anchor position to the specified row and column. If noClip is true, the position is not clipped.

- -

Arguments

rowNumber

Required. The row index to move the anchor to

-
columnNumber

Required. The column index to move the anchor to

-
noClipBoolean

Required. Identifies if you want the position to be clipped

-
-
-
-
-
-
-
- - - - - -
-
\ No newline at end of file diff --git a/api/background_tokenizer.html b/api/background_tokenizer.html deleted file mode 100644 index c17a2a17bcc..00000000000 --- a/api/background_tokenizer.html +++ /dev/null @@ -1,320 +0,0 @@ - -
-
-
-
-
-

BackgroundTokenizer -

- -
-
-
-
-

Tokenizes the current Document in the background, and caches the tokenized rows for future use.

-

If a certain row is changed, everything below that row is re-tokenized.

- -
-
-
-

Constructors

-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Creates a new BackgroundTokenizer object.

- -
-

Creates a new BackgroundTokenizer object.

- -

Arguments

tokenizerTokenizer

Required. The tokenizer to use

-
editorEditor

Required. The editor to associate with

-
-
-
-
-
-
-

Events

-
-
-
-
-
    -
  • -
      -
    • BackgroundTokenizer.on("update", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Fires whenever the background tokeniziers between a range of rows are going to be updated.

- -
-

Fires whenever the background tokeniziers between a range of rows are going to be updated.

- -

Arguments

eObject

Required. An object containing two properties, first and last, which indicate the rows of the region being updated.

-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • BackgroundTokenizer.fireUpdateEvent(Number firstRow, Number lastRow)
    • -
    -
      -
    -
  • -
-
-
-

Emits the 'update' event. firstRow and lastRow are used to define the boundaries of the region to be updated.

- -
-

Emits the 'update' event. firstRow and lastRow are used to define the boundaries of the region to be updated.

- -

Arguments

firstRowNumber

Required. The starting row region

-
lastRowNumber

Required. The final row region

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • BackgroundTokenizer.getState(Number row)
    • -
    -
      -
    -
  • -
-
-
-

Returns the state of tokenization at the end of a row.

- -
-

Returns the state of tokenization at the end of a row.

- -

Arguments

rowNumber

Required. The row to get state at

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • BackgroundTokenizer.getTokens(Number row)
    • -
    -
      -
    -
  • -
-
-
-

Gives list of tokens of the row. (tokens are cached)

- -
-

Gives list of tokens of the row. (tokens are cached)

- -

Arguments

rowNumber

Required. The row to get tokens at

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • BackgroundTokenizer.setDocument(Document doc)
    • -
    -
      -
    -
  • -
-
-
-

Sets a new document to associate with this object.

- -
-

Sets a new document to associate with this object.

- -

Arguments

docDocument

Required. The new document to associate with

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • BackgroundTokenizer.setTokenizer(Tokenizer tokenizer)
    • -
    -
      -
    -
  • -
-
-
-

Sets a new tokenizer for this object.

- -
-

Sets a new tokenizer for this object.

- -

Arguments

tokenizerTokenizer

Required. The new tokenizer to use

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • BackgroundTokenizer.start(Number startRow)
    • -
    -
      -
    -
  • -
-
-
-

Starts tokenizing at the row indicated.

- -
-

Starts tokenizing at the row indicated.

- -

Arguments

startRowNumber

Required. The row to start at

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • BackgroundTokenizer.stop()
    • -
    -
      -
    -
  • -
-
-
-

Stops tokenizing.

- -
-

Stops tokenizing.

- -
-
-
-
-
-
- - - - - -
-
diff --git a/api/command_manager.html b/api/command_manager.html deleted file mode 100644 index 142ca7411ca..00000000000 --- a/api/command_manager.html +++ /dev/null @@ -1,55 +0,0 @@ - -
-
-
-
-
-

CommandManager -

- -
-
-
-
-

new CommandManager(platform, commands)

- -
-
-
-
- - - - - -
-
\ No newline at end of file diff --git a/api/document.html b/api/document.html deleted file mode 100644 index f1fc2ff5540..00000000000 --- a/api/document.html +++ /dev/null @@ -1,927 +0,0 @@ - -
-
-
-
- -
-
-
-

Contains the text of the document. Document can be attached to several EditSessions.

-

At its core, Documents are just an array of strings, with each row in the document matching up to the array index.

- -
-
-
-

Constructors

-
-
-
-
- -
-
-

Creates a new Document. If text is included, the Document contains those strings; otherwise, it's empty.

- -
-

Creates a new Document. If text is included, the Document contains those strings; otherwise, it's empty.

- -

Arguments

textString | Array

Required. The starting text

-
-
-
-
-
-
-

Events

-
-
-
-
-
    -
  • -
      -
    • Document.on("change", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Fires whenever the document changes.

- -
-

Fires whenever the document changes.

-

Several methods trigger different "change" events. Below is a list of each action type, followed by each property that's also available:

- - -

Arguments

eObject

Required. Contains at least one property called "action". "action" indicates the action that triggered the change. Each action also has a set of additional properties.

-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • Document.applyDeltas(Object deltas)
    • -
    -
      -
    -
  • -
-
-
-

Applies all the changes previously accumulated. These can be either 'includeText', 'insertLines', 'removeText', and 'removeLines'.

- -
-

Applies all the changes previously accumulated. These can be either 'includeText', 'insertLines', 'removeText', and 'removeLines'.

- -

Arguments

deltasObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Creates a new Anchor to define a floating point in the document.

- -
-

Creates a new Anchor to define a floating point in the document.

- -

Arguments

rowNumber

Required. The row number to use

-
columnNumber

Required. The column number to use

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.getAllLines()
    • -
    -
      -
    -
  • -
-
-
-

Returns all lines in the document as string array.

- -
-

Returns all lines in the document as string array. Warning: The caller should not modify this array!

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.getLength()
    • -
    -
      -
    -
  • -
-
-
-

Returns the number of rows in the document.

- -
-

Returns the number of rows in the document.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.getLine(Number row)
    • -
    -
      -
    -
  • -
-
-
-

Returns a verbatim copy of the given line as it is in the document

- -
-

Returns a verbatim copy of the given line as it is in the document

- -

Arguments

rowNumber

Required. The row index to retrieve

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns an array of strings of the rows between firstRow and lastRow. This function is inclusive of lastRow.

- -
-

Returns an array of strings of the rows between firstRow and lastRow. This function is inclusive of lastRow.

- -

Arguments

firstRowNumber

Required. The first row index to retrieve

-
lastRowNumber

Required. The final row index to retrieve

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.getNewLineCharacter() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the newline character that's being used, depending on the value of newLineMode.

- -
-

Returns the newline character that's being used, depending on the value of newLineMode.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.getNewLineMode() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the type of newlines being used; either windows, unix, or auto

- -
-

Returns the type of newlines being used; either windows, unix, or auto

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.getTextRange(Range range)
    • -
    -
      -
    -
  • -
-
-
-

Given a range within the document, this function returns all the text within that range as a single string.

- -
-

Given a range within the document, this function returns all the text within that range as a single string.

- -

Arguments

rangeRange

Required. The range to work with

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.getValue()
    • -
    -
      -
    -
  • -
-
-
-

Returns all the lines in the document as a single string, split by the new line character.

- -
-

Returns all the lines in the document as a single string, split by the new line character.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Converts an index position in a document to a {row, column} object.

- -
-

Converts an index position in a document to a {row, column} object.

-

Index refers to the "absolute position" of a character in the document. For example:

-
var x = 0; // 10 characters, plus one for newline
-var y = -1;
-

Here, y is an index 15: 11 characters for the first row, and 5 characters until y in the second.

- -

Arguments

indexNumber

Required. An index to convert

-
startRowNumber

Required. =0 The row from which to start the conversion

-
-
-
-
-
-
-
-
-
-
- -
-
-

Inserts a block of text and the indicated position.

- -
-

Inserts a block of text and the indicated position.

- -

Arguments

positionObject

Required. The position to start inserting at

-
textString

Required. A chunk of text to insert

-
-
-
-
-
-
-
-
-
-
- -
-
-

Inserts text into the position at the current row. This method also triggers the 'change' event.

- -
-

Inserts text into the position at the current row. This method also triggers the 'change' event.

- -

Arguments

positionObject

Required. The position to insert at

-
textString

Required. A chunk of text

-
-
-
-
-
-
-
-
-
-
- -
-
-

Inserts the elements in lines into the document, starting at the row index given by row. This method also triggers the 'change' event.

- -
-

Inserts the elements in lines into the document, starting at the row index given by row. This method also triggers the 'change' event.

- -

Arguments

rowNumber

Required. The index of the row to insert at

-
linesArray

Required. An array of strings

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.insertNewLine(Object position) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Inserts a new line into the document at the current row's position. This method also triggers the 'change' event.

- -
-

Inserts a new line into the document at the current row's position. This method also triggers the 'change' event.

- -

Arguments

positionObject

Required. The position to insert at

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.isNewLine(String text)
    • -
    -
      -
    -
  • -
-
-
-

Returns true if text is a newline character (either \r\n, \r, or \n).

- -
-

Returns true if text is a newline character (either \r\n, \r, or \n).

- -

Arguments

textString

Required. The text to check

-
-
-
-
-
-
-
-
-
-
- -
-
-

Converts the {row, column} position in a document to the character's index.

- -
-

Converts the {row, column} position in a document to the character's index.

-

Index refers to the "absolute position" of a character in the document. For example:

-
var x = 0; // 10 characters, plus one for newline
-var y = -1;
-

Here, y is an index 15: 11 characters for the first row, and 5 characters until y in the second.

- -

Arguments

posObject

Required. The {row, column} to convert

-
startRowNumber

Required. =0 The row from which to start the conversion

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Removes the range from the document.

- -
-

Removes the range from the document.

- -

Arguments

rangeRange

Required. A specified Range to remove

-
-
-
-
-
-
-
-
-
-
- -
-
-

Removes the specified columns from the row. This method also triggers the 'change' event.

- -
-

Removes the specified columns from the row. This method also triggers the 'change' event.

- -

Arguments

rowNumber

Required. The row to remove from

-
startColumnNumber

Required. The column to start removing at

-
endColumnNumber

Required. The column to stop removing at

-
-
-
-
-
-
-
-
-
-
- -
-
-

Removes a range of full lines. This method also triggers the 'change' event.

- -
-

Removes a range of full lines. This method also triggers the 'change' event.

- -

Arguments

firstRowNumber

Required. The first row to be removed

-
lastRowNumber

Required. The last row to be removed

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.removeNewLine(Number row)
    • -
    -
      -
    -
  • -
-
-
-

Removes the new line between row and the row immediately following it. This method also triggers the 'change' event.

- -
-

Removes the new line between row and the row immediately following it. This method also triggers the 'change' event.

- -

Arguments

rowNumber

Required. The row to check

-
-
-
-
-
-
-
-
-
-
- -
-
-

Replaces a range in the document with the new text.

- -
-

Replaces a range in the document with the new text.

- -

Arguments

rangeRange

Required. A specified Range to replace

-
textString

Required. The new text to use as a replacement

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.revertDeltas(Object deltas)
    • -
    -
      -
    -
  • -
-
-
-

Reverts any changes previously applied. These can be either 'includeText', 'insertLines', 'removeText', and 'removeLines'.

- -
-

Reverts any changes previously applied. These can be either 'includeText', 'insertLines', 'removeText', and 'removeLines'.

- -

Arguments

deltasObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.setNewLineMode(String newLineMode)
    • -
    -
      -
    -
  • -
-
-
-

Sets the new line mode.

- -
-

Sets the new line mode.

- -

Arguments

newLineModeString

Required. The newline mode to use; can be either windows, unix, or auto

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Document.setValue(String text)
    • -
    -
      -
    -
  • -
-
-
-

Replaces all the lines in the current Document with the value of text.

- -
-

Replaces all the lines in the current Document with the value of text.

- -

Arguments

textString

Required. The text to use

-
-
-
-
-
-
-
- - - - - -
-
\ No newline at end of file diff --git a/api/edit_session.html b/api/edit_session.html deleted file mode 100644 index 6df86cc0817..00000000000 --- a/api/edit_session.html +++ /dev/null @@ -1,3235 +0,0 @@ - -
-
-
-
-
-

EditSession -

- -
-
-
-
-

Stores all the data about Editor state providing easy way to change editors state.

-

EditSession can be attached to only one Document. Same Document can be attached to several EditSessions.

- -
-
-
-

Constructors

-
-
-
-
- -
-
-

Sets up a new EditSession and associates it with the given Document and TextMode.

- -
-

Sets up a new EditSession and associates it with the given Document and TextMode.

- -

Arguments

textDocument | String

Required. If text is a Document, it associates the EditSession with it. Otherwise, a new Document is created, with the initial text

-
modeTextMode

Required. The initial language mode to use for the document

-
-
-
-
-
-
-

Events

-
-
-
-
-
    -
  • -
      -
    • EditSession.on("change", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the document changes.

- -
-

Emitted when the document changes.

- -

Arguments

eObject

Required. An object containing a delta of information about the change.

-
-
-
-
-
-
- -
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeBackMarker", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when a back marker changes.

- -
-

Emitted when a back marker changes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeBreakpoint", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change.

- -
-

Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeFold", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when a code fold is added or removed.

- -
-

Emitted when a code fold is added or removed.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeFrontMarker", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when a front marker changes.

- -
-

Emitted when a front marker changes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeMode", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the current mode changes.

- -
-

Emitted when the current mode changes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeOverwrite", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the ability to overwrite text changes, via EditSession.setOverwrite().

- -
-

Emitted when the ability to overwrite text changes, via EditSession.setOverwrite().

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeScrollLeft", function(Number scrollLeft))
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the scroll left changes.

- -
-

Emitted when the scroll left changes.

- -

Arguments

scrollLeftNumber

Required. The new scroll left value

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeScrollTop", function(Number scrollTop))
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the scroll top changes.

- -
-

Emitted when the scroll top changes.

- -

Arguments

scrollTopNumber

Required. The new scroll top value

-
-
-
-
-
-
- -
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeWrapLimit", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the wrapping limit changes.

- -
-

Emitted when the wrapping limit changes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("changeWrapMode", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the wrap mode changes.

- -
-

Emitted when the wrap mode changes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.on("tokenizerUpdate", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Emitted when a background tokenizer asynchronously processes new rows.

- -
-

Emitted when a background tokenizer asynchronously processes new rows.

- -

Arguments

eObject

Required. An object containing one property, "data", that contains information about the changing rows

-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Adds a dynamic marker to the session.

- -
-

Adds a dynamic marker to the session.

- -

Arguments

markerObject

Required. Object with update method

-
inFrontBoolean

Required. Set to true to establish a front marker

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.addGutterDecoration(Number row, String className)
    • -
    -
      -
    -
  • -
-
-
-

Adds className to the row, to be used for CSS stylings and whatnot.

- -
-

Adds className to the row, to be used for CSS stylings and whatnot.

- -

Arguments

rowNumber

Required. The row number

-
classNameString

Required. The class to add

-
-
-
-
-
-
-
-
-
-
- -
-
-

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.

- -
-

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.

- -

Arguments

rangeRange

Required. Define the range of the marker

-
clazzString

Required. Set the CSS class for the marker

-
typeFunction | String

Required. Identify the type of the marker

-
inFrontBoolean

Required. Set to true to establish a front marker

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.clearAnnotations()
    • -
    -
      -
    -
  • -
-
-
-

Clears all the annotations for this session. This function also triggers the 'changeAnnotation' event.

- -
-

Clears all the annotations for this session. This function also triggers the 'changeAnnotation' event.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.clearBreakpoint(Number row)
    • -
    -
      -
    -
  • -
-
-
-

Removes a breakpoint on the row number given by rows. This function also emits the 'changeBreakpoint' event.

- -
-

Removes a breakpoint on the row number given by rows. This function also emits the 'changeBreakpoint' event.

- -

Arguments

rowNumber

Required. A row index

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.clearBreakpoints()
    • -
    -
      -
    -
  • -
-
-
-

Removes all breakpoints on the rows. This function also emites the 'changeBreakpoint' event.

- -
-

Removes all breakpoints on the rows. This function also emites the 'changeBreakpoint' event.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

For the given document row and column, returns the screen column.

- -
-

For the given document row and column, returns the screen column.

- -

Arguments

rowNumber

Required.

-
docColumnNumber

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.documentToScreenPosition(Number docRow, Number docColumn) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Converts document coordinates to screen coordinates. This takes into account code folding, word wrap, tab size, and any other visual modifications.

- -
-

Converts document coordinates to screen coordinates. This takes into account code folding, word wrap, tab size, and any other visual modifications.

- -

Arguments

docRowNumber

Required. The document row to check

-
docColumnNumber

Required. The document column to check

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.documentToScreenRow(Number docRow, Number docColumn)
    • -
    -
      -
    -
  • -
-
-
-

For the given document row and column, returns the screen row.

- -
-

For the given document row and column, returns the screen row.

- -

Arguments

docRowNumber

Required.

-
docColumnNumber

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Duplicates all the text between firstRow and lastRow.

- -
-

Duplicates all the text between firstRow and lastRow.

- -

Arguments

firstRowNumber

Required. The starting row to duplicate

-
lastRowNumber

Required. The final row to duplicate

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getAnnotations() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the annotations for the EditSession.

- -
-

Returns the annotations for the EditSession.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Gets the range of a word, including its right whitespace.

- -
-

Gets the range of a word, including its right whitespace.

- -

Arguments

rowNumber

Required. The row number to start from

-
columnNumber

Required. The column number to start from

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getBreakpoints() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns an array of numbers, indicating which rows have breakpoints.

- -
-

Returns an array of numbers, indicating which rows have breakpoints.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getDocument() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the Document associated with this session.

- -
-

Returns the Document associated with this session.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getDocumentLastRowColumn(Number docRow, Number docColumn)
    • -
    -
      -
    -
  • -
-
-
-

For the given document row and column, this returns the column position of the last screen row.

- -
-

For the given document row and column, this returns the column position of the last screen row.

- -

Arguments

docRowNumber

Required.

-
docColumnNumber

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getDocumentLastRowColumnPosition(Number docRow, Number docColumn)
    • -
    -
      -
    -
  • -
-
-
-

For the given document row and column, this returns the document position of the last row.

- -
-

For the given document row and column, this returns the document position of the last row.

- -

Arguments

docRowNumber

Required.

-
docColumnNumber

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getLength() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the number of rows in the document.

- -
-

Returns the number of rows in the document.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns a verbatim copy of the given line as it is in the document

- -
-

Returns a verbatim copy of the given line as it is in the document

- -

Arguments

rowNumber

Required. The row to retrieve from

-
-
-
-
-
-
-
-
-
-
- -
-
-

Returns an array of strings of the rows between firstRow and lastRow. This function is inclusive of lastRow.

- -
-

Returns an array of strings of the rows between firstRow and lastRow. This function is inclusive of lastRow.

- -

Arguments

firstRowNumber

Required. The first row index to retrieve

-
lastRowNumber

Required. The final row index to retrieve

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getMarkers(Boolean inFront) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns an array containing the IDs of all the markers, either front or back.

- -
-

Returns an array containing the IDs of all the markers, either front or back.

- -

Arguments

inFrontBoolean

Required. If true, indicates you only want front markers; false indicates only back markers

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getMode() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current text mode.

- -
-

Returns the current text mode.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getNewLineMode() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current new line mode.

- -
-

Returns the current new line mode.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getOverwrite()
    • -
    -
      -
    -
  • -
-
-
-

Returns true if overwrites are enabled; false otherwise.

- -
-

Returns true if overwrites are enabled; false otherwise.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns number of screenrows in a wrapped line.

- -
-

Returns number of screenrows in a wrapped line.

- -

Arguments

rowNumber

Required. The row number to check

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getRowSplitData(Object row) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

For the given row, this returns the split data.

- -
-

For the given row, this returns the split data.

- -

Arguments

rowObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getScreenLastRowColumn(Number screenRow) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the position (on screen) for the last character in the provided screen row.

- -
-

Returns the position (on screen) for the last character in the provided screen row.

- -

Arguments

screenRowNumber

Required. The screen row to check

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getScreenLength() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the length of the screen.

- -
-

Returns the length of the screen.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getScreenTabSize(Number screenColumn) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

The distance to the next tab stop at the specified screen column.

- -
-

The distance to the next tab stop at the specified screen column.

- -

Arguments

screenColumnNumber

Required. The screen column to check

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getScreenWidth() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the width of the screen.

- -
-

Returns the width of the screen.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getScrollLeft() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the value of the distance between the left of the editor and the leftmost part of the visible content.

- -
-

Returns the value of the distance between the left of the editor and the leftmost part of the visible content.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getScrollTop() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the value of the distance between the top of the editor and the topmost part of the visible content.

- -
-

Returns the value of the distance between the top of the editor and the topmost part of the visible content.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getSelection()
    • -
    -
      -
    -
  • -
-
-
-

Returns selection object.

- -
-

Returns selection object.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getState(Number row)
    • -
    -
      -
    -
  • -
-
-
-

Returns the state of tokenization at the end of a row.

- -
-

Returns the state of tokenization at the end of a row.

- -

Arguments

rowNumber

Required. The row to start at

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getTabSize()
    • -
    -
      -
    -
  • -
-
-
-

Returns the current tab size.

- -
-

Returns the current tab size.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getTabString()
    • -
    -
      -
    -
  • -
-
-
-

Returns the current value for tabs. If the user is using soft tabs, this will be a series of spaces (defined by getTabSize()); otherwise it's simply '\t'.

- -
-

Returns the current value for tabs. If the user is using soft tabs, this will be a series of spaces (defined by getTabSize()); otherwise it's simply '\t'.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getTextRange(Range range) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Given a range within the document, this function returns all the text within that range as a single string.

- -
-

Given a range within the document, this function returns all the text within that range as a single string.

- -

Arguments

rangeRange

Required. The range to work with

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns an object indicating the token at the current row. The object has two properties: index and start.

- -
-

Returns an object indicating the token at the current row. The object has two properties: index and start.

- -

Arguments

rowNumber

Required. The row number to retrieve from

-
columnNumber

Required. The column number to retrieve from

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getTokens(Number row)
    • -
    -
      -
    -
  • -
-
-
-

Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.

- -
-

Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.

- -

Arguments

rowNumber

Required. The row to start at

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getUndoManager()
    • -
    -
      -
    -
  • -
-
-
-

Returns the current undo manager.

- -
-

Returns the current undo manager.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getUseSoftTabs() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if soft tabs are being used, false otherwise.

- -
-

Returns true if soft tabs are being used, false otherwise.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getUseWorker()
    • -
    -
      -
    -
  • -
-
-
-

Returns true if workers are being used.

- -
-

Returns true if workers are being used.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getUseWrapMode() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if wrap mode is being used; false otherwise.

- -
-

Returns true if wrap mode is being used; false otherwise.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getValue() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current Document as a string.

- -
-

Returns the current Document as a string.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Given a starting row and column, this method returns the Range of the first word boundary it finds.

- -
-

Given a starting row and column, this method returns the Range of the first word boundary it finds.

- -

Arguments

rowNumber

Required. The row to start at

-
columnNumber

Required. The column to start at

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getWrapLimit() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the value of wrap limit.

- -
-

Returns the value of wrap limit.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.getWrapLimitRange() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this:

- -
-

Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this:

-

{ min: wrapLimitRange_min, max: wrapLimitRange_max }

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.highlight()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.highlightLines()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Indents all the rows, from startRow to endRow (inclusive), by prefixing each row with the token in indentString.

- -
-

Indents all the rows, from startRow to endRow (inclusive), by prefixing each row with the token in indentString.

-

If indentString contains the '\t' character, it's replaced by whatever is defined by getTabString().

- -

Arguments

startRowNumber

Required. Starting row

-
endRowNumber

Required. Ending row

-
indentStringString

Required. The indent token

-
-
-
-
-
-
-
-
-
-
- -
-
-

Inserts a block of text and the indicated position.

- -
-

Inserts a block of text and the indicated position.

- -

Arguments

positionObject

Required. The position {row, column} to start inserting at

-
textString

Required. A chunk of text to insert

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.isTabStop(Object position)
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the character at the position is a soft tab.

- -
-

Returns true if the character at the position is a soft tab.

- -

Arguments

positionObject

Required. The position to check

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Shifts all the lines in the document down one, starting from firstRow and ending at lastRow.

- -
-

Shifts all the lines in the document down one, starting from firstRow and ending at lastRow.

- -

Arguments

firstRowNumber

Required. The starting row to move down

-
lastRowNumber

Required. The final row to move down

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Shifts all the lines in the document up one, starting from firstRow and ending at lastRow.

- -
-

Shifts all the lines in the document up one, starting from firstRow and ending at lastRow.

- -

Arguments

firstRowNumber

Required. The starting row to move up

-
lastRowNumber

Required. The final row to move up

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Moves a range of text from the given range to the given position. toPosition is an object that looks like this:

-
   { row: newRowLocation, column: newColumnLocation }
- -
-

Moves a range of text from the given range to the given position. toPosition is an object that looks like this:

-
   { row: newRowLocation, column: newColumnLocation }
- -

Arguments

fromRangeRange

Required. The range of text you want moved within the document

-
toPositionObject

Required. The location (row and column) where you want to move the text to

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.onChange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.onChangeFold()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.onReloadTokenizer(Object e)
    • -
    -
      -
    -
  • -
-
-
-

Reloads all the tokens on the current session. This function calls BackgroundTokenizer.start () to all the rows; it also emits the 'tokenizerUpdate' event.

- -
-

Reloads all the tokens on the current session. This function calls BackgroundTokenizer.start () to all the rows; it also emits the 'tokenizerUpdate' event.

- -

Arguments

eObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.outdentRows(Range range)
    • -
    -
      -
    -
  • -
-
-
-

Outdents all the rows defined by the start and end properties of range.

- -
-

Outdents all the rows defined by the start and end properties of range.

- -

Arguments

rangeRange

Required. A range of rows

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.redo()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Re-implements a previously undone change to your document.

- -
-

Re-implements a previously undone change to your document.

- -

Arguments

deltasArray

Required. An array of previous changes

-
dontSelectBoolean

Required. If true, doesn't select the range of where the change occurred

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Removes the range from the document.

- -
-

Removes the range from the document.

- -

Arguments

rangeRange

Required. A specified Range to remove

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.removeGutterDecoration(Number row, String className)
    • -
    -
      -
    -
  • -
-
-
-

Removes className from the row.

- -
-

Removes className from the row.

- -

Arguments

rowNumber

Required. The row number

-
classNameString

Required. The class to add

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.removeMarker(Number markerId)
    • -
    -
      -
    -
  • -
-
-
-

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.

- -
-

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.

- -

Arguments

markerIdNumber

Required. A number representing a marker

-
-
-
-
-
-
-
-
-
-
- -
-
-

Replaces a range in the document with the new text.

- -
-

Replaces a range in the document with the new text.

- -

Arguments

rangeRange

Required. A specified Range to replace

-
textString

Required. The new text to use as a replacement

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.reset()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.resetCaches()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.screenToDocumentColumn()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.screenToDocumentPosition(Number screenRow, Number screenColumn) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

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.

- -
-

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.

- -

Arguments

screenRowNumber

Required. The screen row to check

-
screenColumnNumber

Required. The screen column to check

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.screenToDocumentRow()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setAnnotations(Array annotations)
    • -
    -
      -
    -
  • -
-
-
-

Sets annotations for the EditSession. This functions emits the 'changeAnnotation' event.

- -
-

Sets annotations for the EditSession. This functions emits the 'changeAnnotation' event.

- -

Arguments

annotationsArray

Required. A list of annotations

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setBreakpoint(Number row, String className)
    • -
    -
      -
    -
  • -
-
-
-

Sets a breakpoint on the row number given by rows. This function also emites the 'changeBreakpoint' event.

- -
-

Sets a breakpoint on the row number given by rows. This function also emites the 'changeBreakpoint' event.

- -

Arguments

rowNumber

Required. A row index

-
classNameString

Required. Class of the breakpoint

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setBreakpoints(Array rows)
    • -
    -
      -
    -
  • -
-
-
-

Sets a breakpoint on every row number given by rows. This function also emites the 'changeBreakpoint' event.

- -
-

Sets a breakpoint on every row number given by rows. This function also emites the 'changeBreakpoint' event.

- -

Arguments

rowsArray

Required. An array of row indices

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setDocument(Document doc)
    • -
    -
      -
    -
  • -
-
-
-

Sets the EditSession to point to a new Document. If a BackgroundTokenizer exists, it also points to doc.

- -
-

Sets the EditSession to point to a new Document. If a BackgroundTokenizer exists, it also points to doc.

- -

Arguments

docDocument

Required. The new Document to use

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setMode()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setNewLineMode(String newLineMode)
    • -
    -
      -
    -
  • -
-
-
-

Sets the new line mode.

- -
-

Sets the new line mode.

- -

Arguments

newLineModeString

Required. The newline mode to use; can be either windows, unix, or auto

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setOverwrite(Boolean overwrite)
    • -
    -
      -
    -
  • -
-
-
-

Pass in true to enable overwrites in your session, or false to disable.

- -
-

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.

- -

Arguments

overwriteBoolean

Required. Defines wheter or not to set overwrites

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setScrollLeft(Object scrollLeft)
    • -
    -
      -
    -
  • -
-
-
-

Sets the value of the distance between the left of the editor and the leftmost part of the visible content.

- -
-

Sets the value of the distance between the left of the editor and the leftmost part of the visible content.

- -

Arguments

scrollLeftObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setScrollTop(Number scrollTop)
    • -
    -
      -
    -
  • -
-
-
-

This function sets the scroll top value. It also emits the 'changeScrollTop' event.

- -
-

This function sets the scroll top value. It also emits the 'changeScrollTop' event.

- -

Arguments

scrollTopNumber

Required. The new scroll top value

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setTabSize(Number tabSize)
    • -
    -
      -
    -
  • -
-
-
-

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.

- -
-

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.

- -

Arguments

tabSizeNumber

Required. The new tab size

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setUndoManager(UndoManager undoManager)
    • -
    -
      -
    -
  • -
-
-
-

Sets the undo manager.

- -
-

Sets the undo manager.

- -

Arguments

undoManagerUndoManager

Required. The new undo manager

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setUndoSelect(Boolean enable)
    • -
    -
      -
    -
  • -
-
-
-

Enables or disables highlighting of the range where an undo occured.

- -
-

Enables or disables highlighting of the range where an undo occured.

- -

Arguments

enableBoolean

Required. If true, selects the range of the reinserted change

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setUseSoftTabs(Boolean useSoftTabs)
    • -
    -
      -
    -
  • -
-
-
-

Pass true to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character ('\t').

- -
-

Pass true to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character ('\t').

- -

Arguments

useSoftTabsBoolean

Required. Value indicating whether or not to use soft tabs

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setUseWorker(Boolean useWorker)
    • -
    -
      -
    -
  • -
-
-
-

Identifies if you want to use a worker for the EditSession.

- -
-

Identifies if you want to use a worker for the EditSession.

- -

Arguments

useWorkerBoolean

Required. Set to true to use a worker

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setUseWrapMode(Boolean useWrapMode)
    • -
    -
      -
    -
  • -
-
-
-

Sets whether or not line wrapping is enabled. If useWrapMode is different than the current value, the 'changeWrapMode' event is emitted.

- -
-

Sets whether or not line wrapping is enabled. If useWrapMode is different than the current value, the 'changeWrapMode' event is emitted.

- -

Arguments

useWrapModeBoolean

Required. Enable (or disable) wrap mode

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.setValue(String text)
    • -
    -
      -
    -
  • -
-
-
-

Sets the session text.

- -
-

Sets the session text.

- -

Arguments

textString

Required. The new text to place

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

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.

- -
-

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.

- -

Arguments

minNumber

Required. The minimum wrap value (the left side wrap)

-
maxNumber

Required. The maximum wrap value (the right side wrap)

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.toggleOverwrite()
    • -
    -
      -
    -
  • -
-
-
-

Sets the value of overwrite to the opposite of whatever it currently is.

- -
-

Sets the value of overwrite to the opposite of whatever it currently is.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.toString() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current Document as a string.

- -
-

Returns the current Document as a string.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • EditSession.undo()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Reverts previous changes to your document.

- -
-

Reverts previous changes to your document.

- -

Arguments

deltasArray

Required. An array of previous changes

-
dontSelectBoolean

Required. If true, doesn't select the range of where the change occurred

-
-
-
-
-
-
-
- - - - - -
-
diff --git a/api/editor.html b/api/editor.html deleted file mode 100644 index 46216eb60f0..00000000000 --- a/api/editor.html +++ /dev/null @@ -1,4689 +0,0 @@ - -
-
-
-
-
-

Editor -

- -
-
-
-
-

The main entry point into the Ace functionality.

-

The Editor manages the EditSession (which manages Documents), as well as the VirtualRenderer, which draws everything to the screen.

-

Event sessions dealing with the mouse and keyboard are bubbled up from Document to the Editor, which decides what to do with them.

- -
-
-
-

Constructors

-
-
-
-
- -
-
-

Creates a new Editor object.

- -
-

Creates a new Editor object.

- -

Arguments

rendererVirtualRenderer

Required. Associated VirtualRenderer that draws everything

-
sessionEditSession

Required. The EditSession to refer to

-
-
-
-
-
-
-

Events

-
-
-
-
-
    -
  • -
      -
    • Editor.on("blur", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted once the editor has been blurred.

- -
-

Emitted once the editor has been blurred.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.on("change", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Emitted whenever the document is changed.

- -
-

Emitted whenever the document is changed.

- -

Arguments

eObject

Required. Contains a single property, data, which has the delta of changes

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.on("changeSelectionStyle", function(Object data))
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the selection style changes, via Editor.setSelectionStyle().

- -
-

Emitted when the selection style changes, via Editor.setSelectionStyle().

- -

Arguments

dataObject

Required. Contains one property, data, which indicates the new selection style

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.on("changeSession", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Emitted whenever the EditSession changes.

- -
-

Emitted whenever the EditSession changes.

- -

Arguments

eObject

Required. An object with two properties, oldSession and session, that represent the old and new EditSessions.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.on("copy", function(String text))
    • -
    -
      -
    -
  • -
-
-
-

Emitted when text is copied.

- -
-

Emitted when text is copied.

- -

Arguments

textString

Required. The copied text

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.on("focus", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted once the editor comes into focus.

- -
-

Emitted once the editor comes into focus.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.on("paste", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Emitted when text is pasted.

- -
-

Emitted when text is pasted.

- -

Arguments

eObject

Required. An object which contains one property, text, that represents the text to be pasted. Editing this property will alter the text that is pasted.

-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • Editor.addSelectionMarker(Range orientedRange) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Adds the selection and cursor.

- -
-

Adds the selection and cursor.

- -

Arguments

orientedRangeRange

Required. A range containing a cursor

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.alignCursors()
    • -
    -
      -
    -
  • -
-
-
-

Aligns the cursors or selected text.

- -
-

Aligns the cursors or selected text.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.blockOutdent()
    • -
    -
      -
    -
  • -
-
-
-

Outdents the current line.

- -
-

Outdents the current line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.blur()
    • -
    -
      -
    -
  • -
-
-
-

Blurs the current textInput.

- -
-

Blurs the current textInput.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.centerSelection()
    • -
    -
      -
    -
  • -
-
-
-

Attempts to center the current selection on the screen.

- -
-

Attempts to center the current selection on the screen.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.clearSelection()
    • -
    -
      -
    -
  • -
-
-
-

Empties the selection (by de-selecting it). This function also emits the 'changeSelection' event.

- -
-

Empties the selection (by de-selecting it). This function also emits the 'changeSelection' event.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.copyLinesDown() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Copies all the selected lines down one row.

- -
-

Copies all the selected lines down one row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.copyLinesUp() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Copies all the selected lines up one row.

- -
-

Copies all the selected lines up one row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.destroy()
    • -
    -
      -
    -
  • -
-
-
-

Cleans up the entire editor.

- -
-

Cleans up the entire editor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.duplicateSelection()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.execCommand()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.exitMultiSelectMode()
    • -
    -
      -
    -
  • -
-
-
-

Removes all the selections except the last added one.

- -
-

Removes all the selections except the last added one.

- -
-
-
-
-
-
-
-
-
- -
-
-

Attempts to find needle within the document. For more information on options, see Search.

- -
-

Attempts to find needle within the document. For more information on options, see Search.

- -

Arguments

needleString

Required. The text to search for (optional)

-
optionsObject

Required. An object defining various search properties

-
animateBoolean

Required. If true animate scrolling

-
-
-
-
-
-
-
-
-
-
- -
-
-

Finds and selects all the occurrences of needle.

- -
-

Finds and selects all the occurrences of needle.

- -

Arguments

TheString

Required. Text to find

-
TheObject

Required. Search options

-
keepsBoolean

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Performs another search for needle in the document. For more information on options, see Search.

- -
-

Performs another search for needle in the document. For more information on options, see Search.

- -

Arguments

optionsObject

Required. Search options

-
animateBoolean

Required. If true animate scrolling

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Performs a search for needle backwards. For more information on options, see Search.

- -
-

Performs a search for needle backwards. For more information on options, see Search.

- -

Arguments

optionsObject

Required. Search options

-
animateBoolean

Required. If true animate scrolling

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.focus()
    • -
    -
      -
    -
  • -
-
-
-

Brings the current textInput into focus.

- -
-

Brings the current textInput into focus.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Executes a command for each selection range.

- -
-

Executes a command for each selection range.

- -

Arguments

cmdString

Required. The command to execute

-
argsString

Required. Any arguments for the command

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getAnimatedScroll()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getBehavioursEnabled() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the behaviors are currently enabled. "Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.

- -
-

Returns true if the behaviors are currently enabled. "Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getCopyText() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the string of text currently highlighted.

- -
-

Returns the string of text currently highlighted.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getCursorPosition() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Gets the current position of the cursor.

- -
-

Gets the current position of the cursor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getCursorPositionScreen() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the screen position of the cursor.

- -
-

Returns the screen position of the cursor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getDisplayIndentGuides()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getDragDelay() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current mouse drag delay.

- -
-

Returns the current mouse drag delay.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getFadeFoldWidgets()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getFirstVisibleRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the index of the first visible row.

- -
-

Returns the index of the first visible row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getHighlightActiveLine() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if current lines are always highlighted.

- -
-

Returns true if current lines are always highlighted.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getHighlightGutterLine()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getHighlightSelectedWord() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if currently highlighted words are to be highlighted.

- -
-

Returns true if currently highlighted words are to be highlighted.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getKeyboardHandler() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the keyboard handler, such as "vim" or "windows".

- -
-

Returns the keyboard handler, such as "vim" or "windows".

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getLastSearchOptions() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns an object containing all the search options. For more information on options, see Search.

- -
-

Returns an object containing all the search options. For more information on options, see Search.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getLastVisibleRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the index of the last visible row.

- -
-

Returns the index of the last visible row.

- -
-
-
-
-
- -
-
-
-
-
    -
  • -
      -
    • Editor.getOverwrite() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if overwrites are enabled; false otherwise.

- -
-

Returns true if overwrites are enabled; false otherwise.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getPrintMarginColumn() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the column number of where the print margin is.

- -
-

Returns the column number of where the print margin is.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getReadOnly() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the editor is set to read-only mode.

- -
-

Returns true if the editor is set to read-only mode.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getScrollSpeed() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the value indicating how fast the mouse scroll speed is (in milliseconds).

- -
-

Returns the value indicating how fast the mouse scroll speed is (in milliseconds).

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getSelection() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns selection object.

- -
-

Returns selection object.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getSelectionRange() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the Range for the selected text.

- -
-

Returns the Range for the selected text.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getSelectionStyle() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current selection style.

- -
-

Returns the current selection style.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns the current session being used.

- -
-

Returns the current session being used.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getShowFoldWidgets() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the fold widgets are shown.

- -
-

Returns true if the fold widgets are shown.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getShowInvisibles() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if invisible characters are being shown.

- -
-

Returns true if invisible characters are being shown.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getShowPrintMargin() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the print margin is being shown.

- -
-

Returns true if the print margin is being shown.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getTheme() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the path of the current theme.

- -
-

Returns the path of the current theme.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getValue() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current session's content.

- -
-

Returns the current session's content.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.getWrapBehavioursEnabled()
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the wrapping behaviors are currently enabled.

- -
-

Returns true if the wrapping behaviors are currently enabled.

- -
-
-
-
-
-
-
-
-
- -
-
-

Moves the cursor to the specified line number, and also into the indicated column.

- -
-

Moves the cursor to the specified line number, and also into the indicated column.

- -

Arguments

lineNumberNumber

Required. The line number to go to

-
columnNumber

Required. A column number to go to

-
animateBoolean

Required. If true animates scrolling

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.gotoPageDown()
    • -
    -
      -
    -
  • -
-
-
-

Shifts the document to wherever "page down" is, as well as moving the cursor position.

- -
-

Shifts the document to wherever "page down" is, as well as moving the cursor position.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.gotoPageUp()
    • -
    -
      -
    -
  • -
-
-
-

Shifts the document to wherever "page up" is, as well as moving the cursor position.

- -
-

Shifts the document to wherever "page up" is, as well as moving the cursor position.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.indent()
    • -
    -
      -
    -
  • -
-
-
-

Indents the current line.

- -
-

Indents the current line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.insert(String text)
    • -
    -
      -
    -
  • -
-
-
-

Inserts text into wherever the cursor is pointing.

- -
-

Inserts text into wherever the cursor is pointing.

- -

Arguments

textString

Required. The new text to add

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.isFocused() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the current textInput is in focus.

- -
-

Returns true if the current textInput is in focus.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Indicates if the entire row is currently visible on the screen.

- -
-

Indicates if the entire row is currently visible on the screen.

- -

Arguments

rowNumber

Required. The row to check

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Indicates if the row is currently visible on the screen.

- -
-

Indicates if the row is currently visible on the screen.

- -

Arguments

rowNumber

Required. The row to check

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.jumpToMatching(Object select)
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor's row and column to the next matching bracket.

- -
-

Moves the cursor's row and column to the next matching bracket.

- -

Arguments

selectObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.modifyNumber(Number amount)
    • -
    -
      -
    -
  • -
-
-
-

If the character before the cursor is a number, this functions changes its value by amount.

- -
-

If the character before the cursor is a number, this functions changes its value by amount.

- -

Arguments

amountNumber

Required. The value to change the numeral by (can be negative to decrease value)

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Moves the cursor to the specified row and column. Note that this does not de-select the current selection.

- -
-

Moves the cursor to the specified row and column. Note that this does not de-select the current selection.

- -

Arguments

rowNumber

Required. The new row number

-
columnNumber

Required. The new column number

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.moveCursorToPosition(Object pos)
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the position indicated by pos.row and pos.column.

- -
-

Moves the cursor to the position indicated by pos.row and pos.column.

- -

Arguments

posObject

Required. An object with two properties, row and column

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.moveLinesDown() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Shifts all the selected lines down one row.

- -
-

Shifts all the selected lines down one row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.moveLinesUp() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Shifts all the selected lines up one row.

- -
-

Shifts all the selected lines up one row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.moveText()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateDown(Number times)
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.

- -
-

Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.

- -

Arguments

timesNumber

Required. The number of times to change navigation

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateFileEnd()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the end of the current file. Note that this does de-select the current selection.

- -
-

Moves the cursor to the end of the current file. Note that this does de-select the current selection.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateFileStart()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the start of the current file. Note that this does de-select the current selection.

- -
-

Moves the cursor to the start of the current file. Note that this does de-select the current selection.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateLeft(Number times)
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.

- -
-

Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.

- -

Arguments

timesNumber

Required. The number of times to change navigation

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateLineEnd()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the end of the current line. Note that this does de-select the current selection.

- -
-

Moves the cursor to the end of the current line. Note that this does de-select the current selection.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateLineStart()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the start of the current line. Note that this does de-select the current selection.

- -
-

Moves the cursor to the start of the current line. Note that this does de-select the current selection.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateRight(Number times)
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.

- -
-

Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.

- -

Arguments

timesNumber

Required. The number of times to change navigation

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Moves the cursor to the specified row and column. Note that this does de-select the current selection.

- -
-

Moves the cursor to the specified row and column. Note that this does de-select the current selection.

- -

Arguments

rowNumber

Required. The new row number

-
columnNumber

Required. The new column number

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateUp(Number times)
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.

- -
-

Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.

- -

Arguments

timesNumber

Required. The number of times to change navigation

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateWordLeft()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.

- -
-

Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.navigateWordRight()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.

- -
-

Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onBlur()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onChangeAnnotation()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onChangeBackMarker()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onChangeBreakpoint()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onChangeFold()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onChangeFrontMarker()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onChangeMode()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onChangeWrapLimit()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onChangeWrapMode()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onCommandKey()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onCompositionEnd()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onCompositionStart()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onCompositionUpdate()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onCopy()
    • -
    -
      -
    -
  • -
-
-
-

Called whenever a text "copy" happens.

- -
-

Called whenever a text "copy" happens.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onCursorChange()
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the selection changes.

- -
-

Emitted when the selection changes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onCut()
    • -
    -
      -
    -
  • -
-
-
-

Called whenever a text "cut" happens.

- -
-

Called whenever a text "cut" happens.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onDocumentChange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onFocus()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onPaste(String text)
    • -
    -
      -
    -
  • -
-
-
-

Called whenever a text "paste" happens.

- -
-

Called whenever a text "paste" happens.

- -

Arguments

textString

Required. The pasted text

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onScrollLeftChange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onScrollTopChange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onSelectionChange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onTextInput()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.onTokenizerUpdate()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.redo()
    • -
    -
      -
    -
  • -
-
-
-

Perform a redo operation on the document, reimplementing the last change.

- -
-

Perform a redo operation on the document, reimplementing the last change.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.remove(String dir)
    • -
    -
      -
    -
  • -
-
-
-

Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.

- -
-

Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.

- -

Arguments

dirString

Required. The direction of the deletion to occur, either "left" or "right"

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.removeLines()
    • -
    -
      -
    -
  • -
-
-
-

Removes all the lines in the current selection

- -
-

Removes all the lines in the current selection

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.removeSelectionMarker(Range The)
    • -
    -
      -
    -
  • -
-
-
-

Removes the selection marker.

- -
-

Removes the selection marker.

- -

Arguments

TheRange

Required. selection range added with addSelectionMarker().

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.removeToLineEnd()
    • -
    -
      -
    -
  • -
-
-
-

Removes all the words to the right of the current selection, until the end of the line.

- -
-

Removes all the words to the right of the current selection, until the end of the line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.removeToLineStart()
    • -
    -
      -
    -
  • -
-
-
-

Removes all the words to the left of the current selection, until the start of the line.

- -
-

Removes all the words to the left of the current selection, until the start of the line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.removeWordLeft()
    • -
    -
      -
    -
  • -
-
-
-

Removes the word directly to the left of the current selection.

- -
-

Removes the word directly to the left of the current selection.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.removeWordRight()
    • -
    -
      -
    -
  • -
-
-
-

Removes the word directly to the right of the current selection.

- -
-

Removes the word directly to the right of the current selection.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Replaces the first occurrence of options.needle with the value in replacement.

- -
-

Replaces the first occurrence of options.needle with the value in replacement.

- -

Arguments

replacementString

Required. The text to replace with

-
optionsObject

Required. The Search options to use

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Replaces all occurrences of options.needle with the value in replacement.

- -
-

Replaces all occurrences of options.needle with the value in replacement.

- -

Arguments

replacementString

Required. The text to replace with

-
optionsObject

Required. The Search options to use

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Triggers a resize of the editor.

- -
-

Triggers a resize of the editor.

- -

Arguments

forceBoolean

Required. If true, recomputes the size, even if the height and width haven't changed

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.revealRange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.scrollPageDown()
    • -
    -
      -
    -
  • -
-
-
-

Scrolls the document to wherever "page down" is, without changing the cursor position.

- -
-

Scrolls the document to wherever "page down" is, without changing the cursor position.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.scrollPageUp()
    • -
    -
      -
    -
  • -
-
-
-

Scrolls the document to wherever "page up" is, without changing the cursor position.

- -
-

Scrolls the document to wherever "page up" is, without changing the cursor position.

- -
-
-
-
-
-
-
-
-
- -
-
-

Scrolls to a line. If center is true, it puts the line in middle of screen (or attempts to).

- -
-

Scrolls to a line. If center is true, it puts the line in middle of screen (or attempts to).

- -

Arguments

lineNumber

Required. The line to scroll to

-
centerBoolean

Required. If true

-
animateBoolean

Required. If true animates scrolling

-
callbackFunction

Required. Function to be called when the animation has finished

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.scrollToRow(Object row)
    • -
    -
      -
    -
  • -
-
-
-

Moves the editor to the specified row.

- -
-

Moves the editor to the specified row.

- -

Arguments

rowObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.selectAll()
    • -
    -
      -
    -
  • -
-
-
-

Selects all the text in editor.

- -
-

Selects all the text in editor.

- -
-
-
-
-
-
-
-
-
- -
-
-

Finds the next occurrence of text in an active selection and adds it to the selections.

- -
-

Finds the next occurrence of text in an active selection and adds it to the selections.

- -

Arguments

dirNumber

Required. The direction of lines to select: -1 for up, 1 for down

-
skipBoolean

Required. If true, removes the active selection range

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Adds a cursor above or below the active cursor.

- -
-

Adds a cursor above or below the active cursor.

- -

Arguments

dirNumber

Required. The direction of lines to select: -1 for up, 1 for down

-
skipBoolean

Required. If true, removes the active selection range

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.selectPageDown()
    • -
    -
      -
    -
  • -
-
-
-

Selects the text from the current position of the document until where a "page down" finishes.

- -
-

Selects the text from the current position of the document until where a "page down" finishes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.selectPageUp()
    • -
    -
      -
    -
  • -
-
-
-

Selects the text from the current position of the document until where a "page up" finishes.

- -
-

Selects the text from the current position of the document until where a "page up" finishes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setAnimatedScroll()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setBehavioursEnabled(Boolean enabled)
    • -
    -
      -
    -
  • -
-
-
-

Specifies whether to use behaviors or not. "Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.

- -
-

Specifies whether to use behaviors or not. "Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.

- -

Arguments

enabledBoolean

Required. Enables or disables behaviors

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setDisplayIndentGuides()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setDragDelay(Number dragDelay)
    • -
    -
      -
    -
  • -
-
-
-

Sets the delay (in milliseconds) of the mouse drag.

- -
-

Sets the delay (in milliseconds) of the mouse drag.

- -

Arguments

dragDelayNumber

Required. A value indicating the new delay

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setFadeFoldWidgets()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setFontSize(Number size)
    • -
    -
      -
    -
  • -
-
-
-

Set a new font size (in pixels) for the editor text.

- -
-

Set a new font size (in pixels) for the editor text.

- -

Arguments

sizeNumber

Required. A font size

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setHighlightActiveLine(Boolean shouldHighlight)
    • -
    -
      -
    -
  • -
-
-
-

Determines whether or not the current line should be highlighted.

- -
-

Determines whether or not the current line should be highlighted.

- -

Arguments

shouldHighlightBoolean

Required. Set to true to highlight the current line

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setHighlightGutterLine()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setHighlightSelectedWord(Boolean shouldHighlight)
    • -
    -
      -
    -
  • -
-
-
-

Determines if the currently selected word should be highlighted.

- -
-

Determines if the currently selected word should be highlighted.

- -

Arguments

shouldHighlightBoolean

Required. Set to true to highlight the currently selected word

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setKeyboardHandler(String keyboardHandler)
    • -
    -
      -
    -
  • -
-
-
-

Sets a new key handler, such as "vim" or "windows".

- -
-

Sets a new key handler, such as "vim" or "windows".

- -

Arguments

keyboardHandlerString

Required. The new key handler

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setOverwrite(Boolean overwrite)
    • -
    -
      -
    -
  • -
-
-
-

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.

- -
-

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.

- -

Arguments

overwriteBoolean

Required. Defines whether or not to set overwrites

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setPrintMarginColumn(Number showPrintMargin)
    • -
    -
      -
    -
  • -
-
-
-

Sets the column defining where the print margin should be.

- -
-

Sets the column defining where the print margin should be.

- -

Arguments

showPrintMarginNumber

Required. Specifies the new print margin

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setReadOnly(Boolean readOnly)
    • -
    -
      -
    -
  • -
-
-
-

If readOnly is true, then the editor is set to read-only mode, and none of the content can change.

- -
-

If readOnly is true, then the editor is set to read-only mode, and none of the content can change.

- -

Arguments

readOnlyBoolean

Required. Specifies whether the editor can be modified or not

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setScrollSpeed(Number speed)
    • -
    -
      -
    -
  • -
-
-
-

Sets how fast the mouse scrolling should do.

- -
-

Sets how fast the mouse scrolling should do.

- -

Arguments

speedNumber

Required. A value indicating the new speed (in milliseconds)

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setSelectionStyle(String style)
    • -
    -
      -
    -
  • -
-
-
-

Indicates how selections should occur.

- -
-

Indicates how selections should occur.

-

By default, selections are set to "line". There are no other styles at the moment, -although this code change in the future.

-

This function also emits the 'changeSelectionStyle' event.

- -

Arguments

styleString

Required. The new selection style

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Sets a new editsession to use. This method also emits the 'changeSession' event.

- -
-

Sets a new editsession to use. This method also emits the 'changeSession' event.

- -

Arguments

sessionEditSession

Required. The new session to use

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setShowFoldWidgets(Boolean show)
    • -
    -
      -
    -
  • -
-
-
-

Indicates whether the fold widgets are shown or not.

- -
-

Indicates whether the fold widgets are shown or not.

- -

Arguments

showBoolean

Required. Specifies whether the fold widgets are shown

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setShowInvisibles(Boolean showInvisibles)
    • -
    -
      -
    -
  • -
-
-
-

If showInvisibles is set to true, invisible characters—like spaces or new lines—are show in the editor.

- -
-

If showInvisibles is set to true, invisible characters—like spaces or new lines—are show in the editor.

- -

Arguments

showInvisiblesBoolean

Required. Specifies whether or not to show invisible characters

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setShowPrintMargin(Boolean showPrintMargin)
    • -
    -
      -
    -
  • -
-
-
-

If showPrintMargin is set to true, the print margin is shown in the editor.

- -
-

If showPrintMargin is set to true, the print margin is shown in the editor.

- -

Arguments

showPrintMarginBoolean

Required. Specifies whether or not to show the print margin

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setStyle(String style)
    • -
    -
      -
    -
  • -
-
-
-

Adds a new class, style, to the editor.

- -
-

Adds a new class, style, to the editor.

- -

Arguments

styleString

Required. A class name

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setTheme(String theme)
    • -
    -
      -
    -
  • -
-
-
-

Sets a new theme for the editor. theme should exist, and be a directory path, like ace/theme/textmate.

- -
-

Sets a new theme for the editor. theme should exist, and be a directory path, like ace/theme/textmate.

- -

Arguments

themeString

Required. The path to a theme

-
-
-
-
-
-
-
-
-
-
- -
-
-

Sets the current document to val.

- -
-

Sets the current document to val.

- -

Arguments

valString

Required. The new value to set for the document

-
cursorPosNumber

Required. Where to set the new value. undefined or 0 is selectAll, -1 is at the document start, and 1 is at the end

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.setWrapBehavioursEnabled(Boolean enabled)
    • -
    -
      -
    -
  • -
-
-
-

Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets -when such a character is typed in.

- -
-

Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets -when such a character is typed in.

- -

Arguments

enabledBoolean

Required. Enables or disables wrapping behaviors

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.sortLines()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.splitLine()
    • -
    -
      -
    -
  • -
-
-
-

Splits the line at the current selection (by inserting an '\n').

- -
-

Splits the line at the current selection (by inserting an '\n').

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.toggleCommentLines()
    • -
    -
      -
    -
  • -
-
-
-

Given the currently selected range, this function either comments all the lines, or uncomments all of them.

- -
-

Given the currently selected range, this function either comments all the lines, or uncomments all of them.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.toggleOverwrite()
    • -
    -
      -
    -
  • -
-
-
-

Sets the value of overwrite to the opposite of whatever it currently is.

- -
-

Sets the value of overwrite to the opposite of whatever it currently is.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.toLowerCase()
    • -
    -
      -
    -
  • -
-
-
-

Converts the current selection entirely into lowercase.

- -
-

Converts the current selection entirely into lowercase.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.toUpperCase()
    • -
    -
      -
    -
  • -
-
-
-

Converts the current selection entirely into uppercase.

- -
-

Converts the current selection entirely into uppercase.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.transposeLetters()
    • -
    -
      -
    -
  • -
-
-
-

Transposes current line.

- -
-

Transposes current line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.transposeSelections(Number dir)
    • -
    -
      -
    -
  • -
-
-
-

Transposes the selected ranges.

- -
-

Transposes the selected ranges.

- -

Arguments

dirNumber

Required. The direction to rotate selections

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.undo()
    • -
    -
      -
    -
  • -
-
-
-

Perform an undo operation on the document, reverting the last change.

- -
-

Perform an undo operation on the document, reverting the last change.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.unsetStyle(Object style)
    • -
    -
      -
    -
  • -
-
-
-

Removes the class style from the editor.

- -
-

Removes the class style from the editor.

- -

Arguments

styleObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Editor.updateSelectionMarkers()
    • -
    -
      -
    -
  • -
-
-
-

Updates the cursor and marker layers.

- -
-

Updates the cursor and marker layers.

- -
-
-
-
-
-
- - - - - -
-
diff --git a/api/index.html b/api/index.html deleted file mode 100644 index cccaab54bec..00000000000 --- a/api/index.html +++ /dev/null @@ -1,12 +0,0 @@ - -

Ace API Reference

-

Welcome 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.

-

On 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.

- - - - - - -
-
\ No newline at end of file diff --git a/api/placeholder.html b/api/placeholder.html deleted file mode 100644 index fa12a958cbe..00000000000 --- a/api/placeholder.html +++ /dev/null @@ -1,293 +0,0 @@ - -
-
-
-
-
-

PlaceHolder -

- -
-
-
-
-

Constructors

-
-
-
-
-
    -
  • -
      -
    • new PlaceHolder()
    • -
    -
      -
    -
  • -
-
-
-
    -
  • session (Document): The document to associate with the anchor
  • -
  • length (Number): The starting row position
  • -
  • pos (Number): The starting column position
  • -
  • others (String):
  • -
  • mainClass (String):
  • -
  • othersClass (String):
  • -
- -
-
    -
  • session (Document): The document to associate with the anchor
  • -
  • length (Number): The starting row position
  • -
  • pos (Number): The starting column position
  • -
  • others (String):
  • -
  • mainClass (String):
  • -
  • othersClass (String):
  • -
- -
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • PlaceHolder.cancel()
    • -
    -
      -
    -
  • -
-
-
-

PlaceHolder.cancel()

- -
-

PlaceHolder.cancel()

-

TODO

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • PlaceHolder.detach()
    • -
    -
      -
    -
  • -
-
-
-

PlaceHolder.detach()

- -
-

PlaceHolder.detach()

-

TODO

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • PlaceHolder.hideOtherMarkers()
    • -
    -
      -
    -
  • -
-
-
-

PlaceHolder.hideOtherMarkers()

- -
-

PlaceHolder.hideOtherMarkers()

-

Hides all over markers in the EditSession that are not the currently selected one.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • PlaceHolder.onCursorChange(Object event)
    • -
    -
      -
    -
  • -
-
-
-

PlaceHolder@onCursorChange(e)

- -
-

PlaceHolder@onCursorChange(e)

-

Emitted when the cursor changes.

- -

Arguments

eventObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • PlaceHolder.onUpdate(Object event)
    • -
    -
      -
    -
  • -
-
-
-

PlaceHolder@onUpdate(e)

- -
-

PlaceHolder@onUpdate(e)

-

Emitted when the place holder updates.

- -

Arguments

eventObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • PlaceHolder.setup()
    • -
    -
      -
    -
  • -
-
-
-

PlaceHolder.setup()

- -
-

PlaceHolder.setup()

-

TODO

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • PlaceHolder.showOtherMarkers()
    • -
    -
      -
    -
  • -
-
-
-

PlaceHolder.showOtherMarkers()

- -
-

PlaceHolder.showOtherMarkers()

-

TODO

- -
-
-
-
-
-
- - - - - -
-
\ No newline at end of file diff --git a/api/range.html b/api/range.html deleted file mode 100644 index 3416aeade81..00000000000 --- a/api/range.html +++ /dev/null @@ -1,968 +0,0 @@ - -
-
-
-
-
-

Range -

- -
-
-
-
-

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.

- -
-
-
-

Constructors

-
-
-
-
- -
-
-

Creates a new Range object with the given starting and ending row and column points.

- -
-

Creates a new Range object with the given starting and ending row and column points.

- -

Arguments

startRowNumber

Required. The starting row

-
startColumnNumber

Required. The starting column

-
endRowNumber

Required. The ending row

-
endColumnNumber

Required. The ending column

-
-
-
-
-
-
-

Methods

-
-
-
-
- -
-
-

Returns the part of the current Range that occurs within the boundaries of firstRow and lastRow as a new Range object.

- -
-

Returns the part of the current Range that occurs within the boundaries of firstRow and lastRow as a new Range object.

- -

Arguments

firstRowNumber

Required. The starting row

-
lastRowNumber

Required. The ending row

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Range.clone() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns a duplicate of the calling range.

- -
-

Returns a duplicate of the calling range.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Range.collapseRows() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns a range containing the starting and ending rows of the original range, but with a column value of 0.

- -
-

Returns a range containing the starting and ending rows of the original range, but with a column value of 0.

- -
-
-
-
-
-
-
-
-
- -
-
-

Checks the row and column points with the row and column points of the calling range.

- -
-

Checks the row and column points with the row and column points of the calling range.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Checks the row and column points with the row and column points of the calling range.

- -
-

Checks the row and column points with the row and column points of the calling range.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Checks the row and column points with the row and column points of the calling range.

- -
-

Checks the row and column points with the row and column points of the calling range.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Checks the row and column points of p with the row and column points of the calling range.

- -
-

Checks the row and column points of p with the row and column points of the calling range.

- -

Arguments

pRange

Required. A point to compare with

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Compares this range (A) with another range (B).

- -
-

Compares this range (A) with another range (B).

- -

Arguments

rangeRange

Required. A range to compare with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Checks the row and column points with the row and column points of the calling range.

- -
-

Checks the row and column points with the row and column points of the calling range.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Returns true if the row and column provided are within the given range. This can better be expressed as returning true if:

-
   this.start.row <= row <= this.end.row &&
-   this.start.column <= column <= this.end.column
- -
-

Returns true if the row and column provided are within the given range. This can better be expressed as returning true if:

-
   this.start.row <= row <= this.end.row &&
-   this.start.column <= column <= this.end.column
- -

Arguments

rowNumber

Required. A row to check for

-
columnNumber

Required. A column to check for

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Checks the start and end points of range and compares them to the calling range. Returns true if the range is contained within the caller's range.

- -
-

Checks the start and end points of range and compares them to the calling range. Returns true if the range is contained within the caller's range.

- -

Arguments

rangeRange

Required. A range to compare with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Changes the row and column points for the calling range for both the starting and ending points.

- -
-

Changes the row and column points for the calling range for both the starting and ending points.

- -

Arguments

rowNumber

Required. A new row to extend to

-
columnNumber

Required. A new column to extend to

-
-
-
-
-
-
-
-
-
-
- -
-
-

Creates and returns a new Range based on the row and column of the given parameters.

- -
-

Creates and returns a new Range based on the row and column of the given parameters.

- -

Arguments

startRange

Required. A starting point to use

-
endRange

Required. An ending point to use

-
-
-
-
-
-
-
-
-
-
- -
-
-

Returns true if the row and column are within the given range.

- -
-

Returns true if the row and column are within the given range.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Returns true if the row and column are within the given range's ending points.

- -
-

Returns true if the row and column are within the given range's ending points.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Returns true if the row and column are within the given range's starting points.

- -
-

Returns true if the row and column are within the given range's starting points.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns true if passed in range intersects with the one calling this method.

- -
-

Returns true if passed in range intersects with the one calling this method.

- -

Arguments

rangeRange

Required. A range to compare with

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Range.isEmpty()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-

Returns true if the caller's ending row point is the same as row, and if the caller's ending column is the same as column.

- -
-

Returns true if the caller's ending row point is the same as row, and if the caller's ending column is the same as column.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns true if and only if the starting row and column, and ending row and column, are equivalent to those given by range.

- -
-

Returns true if and only if the starting row and column, and ending row and column, are equivalent to those given by range.

- -

Arguments

rangeRange

Required. A range to check against

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Range.isMultiLine() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the range spans across multiple lines.

- -
-

Returns true if the range spans across multiple lines.

- -
-
-
-
-
-
-
-
-
- -
-
-

Returns true if the caller's starting row point is the same as row, and if the caller's starting column is the same as column.

- -
-

Returns true if the caller's starting row point is the same as row, and if the caller's starting column is the same as column.

- -

Arguments

rowNumber

Required. A row point to compare with

-
columnNumber

Required. A column point to compare with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Sets the starting row and column for the range.

- -
-

Sets the starting row and column for the range.

- -

Arguments

rowNumber

Required. A row point to set

-
columnNumber

Required. A column point to set

-
-
-
-
-
-
-
-
-
-
- -
-
-

Sets the starting row and column for the range.

- -
-

Sets the starting row and column for the range.

- -

Arguments

rowNumber

Required. A row point to set

-
columnNumber

Required. A column point to set

-
-
-
-
-
-
-
-
-
-
- -
-
-

Given the current Range, this function converts those starting and ending points into screen positions, and then returns a new Range object.

- -
-

Given the current Range, this function converts those starting and ending points into screen positions, and then returns a new Range object.

- -

Arguments

sessionEditSession

Required. The EditSession to retrieve coordinates from

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Range.toString() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns a string containing the range's row and column information, given like this:

-
   [start.row/start.column] -> [end.row/end.column]
- -
-

Returns a string containing the range's row and column information, given like this:

-
   [start.row/start.column] -> [end.row/end.column]
- -
-
-
-
-
-
- - - - - -
-
diff --git a/api/renderloop.html b/api/renderloop.html deleted file mode 100644 index 59c98a0c5e9..00000000000 --- a/api/renderloop.html +++ /dev/null @@ -1,55 +0,0 @@ - -
-
-
-
-
-

RenderLoop -

- -
-
-
-
-

Batches changes (that force something to be redrawn) in the background.

- -
-
-
-
- - - - - -
-
\ No newline at end of file diff --git a/api/resources/csses/ace_api.css b/api/resources/csses/ace_api.css deleted file mode 100644 index 7a90b4c3f7a..00000000000 --- a/api/resources/csses/ace_api.css +++ /dev/null @@ -1,912 +0,0 @@ -/* - Generic "affects everything" stuff -*/ - -#wrapper .content .column2 { - float: none; -} - -#documentation ul { - font-size: 13px; -} - -#documentation li { - color: black; -} - -pre { - background-color: #FFFFFF; -} - -code { - font-size: 12px; - line-height: 16px; - font-family: 'Ubuntu Mono',Monaco,Consolas,monospace !important; - background-color: #F9F9F9; - border-radius: 3px 3px 3px 3px; - display: inline-block; - padding: 0 4px; - margin: 2px 1px; - color: inherit; -} - -#documentation pre { - margin-top: 10px; - border-radius: none; - box-shadow: none; - background : white; - /*background : #f5f5f5; - border: 0;*/ - - -webkit-border-radius: 6px 6px 0 0; - -moz-border-radius: 6px 6px 0 0; - border-radius: 6px 6px 0 0; - - padding: 5px; -} - -.method pre, .event pre, .property pre { - background : white; -} - -#documentation pre code { - background-color: transparent; - border-radius: none; - box-shadow: none; -} - -#documentation a code { - color: #00438a; -} - -#documentation h2 { - font-size: 26px; -} -#documentation p { - font-size: 13px; -} -#documentation li p:last-child { - margin-bottom : 5px; -} - -#documentation blockquote p{ - font-size: 14px; - font-weight: 500; - line-height: 23px; - font-style: italic; -} - -.alert-message{ - margin-bottom : 13px; -} -/* - Header and shoulders -*/ - -.navbar .nav > li { - float:none; - display:inline-block; - *display:inline; /* ie7 fix */ - zoom:1; /* hasLayout ie7 trigger */ -} - -.navbar .nav > li > a { - padding: 10px 15px 11px; -} - -.navbar { - text-align:center; -} - -#topSection { - width: 1000px; -} -.small_win #topSection { - width: 100%; -} -.small_win #topSection .dropdown { - margin-right: 40%; -} -.navbar .brand { - margin-left: 0px; -} -.brand { - background: transparent url(http://github.com/images/ace_logo_menu.png) no-repeat 33px 5px; - width: 80px; - outline: none; - height: 40px; - padding: 0 10px !important; - border: none; -} -.brand.dropdown-toggle:after { - content: none; - display: block; - height: 40px; - border: none; -} - -.ace_logo { - position: absolute; - top: 45px; - z-index: 20000; - left: 210px; -} - -.headerTitle { - position: relative; - top: 100px; - left: 250px; -} - -/* - Menu venue -*/ - - -h3.api_title { - padding-top: 10px; -} - -ul.menu { - margin-left: 2px; -} - -.menu li { - list-style-image: url(http://github.com/images/menu_disc.png); - margin-bottom: 4px; - font-weight: 700; - padding-left: 10px; - margin-left: 0; -} - -.menu li .menu-item a.menuLink, .menu li .menu-item span.menuLink { - color: #3E7096; - font-weight: 100; -} -.menuTwo { - margin-bottom: 5px; - margin-top: 2px; -} -.menuTwo li .menu-item a.menuLink { - color: #3E7096; - font-weight: 100; -} - -/* need specificity to "beat" the above colors */ -.menu li .menu-item a.currentItem, .menuTwo li .menu-item { - color: #0072bc; -} - -/* - Members and the tabs that represent them -*/ - -.srolled .members { - width: 100%; -/* -webkit-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); - -moz-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); - box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); */ - padding-bottom: 15px; -/* height: 31px;*/ - position: fixed; -} -.shadow.members{ - background: #edf8fd; - box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); - -moz-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); - -o-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); - -webkit-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); -} - -.membersContent { - -/* border-bottom: 0.1em solid #FFF;*/ - height: 3em; - padding-top: 4px; -/* line-height: 4;*/ -/* margin-top: -0.1em;*/ - position: relative; -/* transition-property: border-color, line-height; - transition-duration: 125ms, 250ms; - transition-timing-function: ease-out, ease-out; - -moz-transition-property: border-color, line-height; - -moz-transition-duration: 125ms, 250ms; - -moz-transition-timing-function: ease-out, ease-out; - -o-transition-property: border-color, line-height; - -o-transition-duration: 125ms, 250ms; - -o-transition-timing-function: ease-out, ease-out; - -webkit-transition-property: border-color, line-height; - -webkit-transition-duration: 125ms, 250ms; - -webkit-transition-timing-function: ease-out, ease-out;*/ - - /*transition-duration: 125ms; - transition-property: top; - transition-timing-function: ease-out; - - top : 11px;*/ - z-index: 103; - padding-right: 10px; - margin-right: -5px; - /*width: 700px;*/ -} -.srolledHeader .membersContent { - line-height: 3; -} -.srolled .membersContent { - /*top : 0;*/ - width: 625px; - padding-left: 327px; - margin : 0 auto 0 auto; -} - -.srolled ul.nav { - padding-right: 10px; -} - -.membersBackground { -/* background-color: white; - position: fixed; - z-index: 2; - top: 40px; - left: 0px; - right: 0px; - width: 100%; - height: 55px; - opacity: 0; - display: none; - box-shadow: rgba(0, 0, 0, 0.398438) 1px 4px 6px;*/ - - background-color: transparent; - height: 47px; - /*width: 700px;*/ - position: absolute; -} -.srolled .membersBackground { - position: relative; -} -.srolledHeader .membersBackground { -/* display: block;*/ -} -.memberHeader { - float: left; - padding-right: 10px; - margin-bottom: 5px; - position: absolute; - padding-top: 4px; - -} - -ul.tabs li:first-child ul{ - left: -63px; -} - -.tabs a.menu:after, .tabs .dropdown-toggle:after { - margin-top: 22px; -} - -.nav .dropdown-toggle .caret { - margin-top: 12px; - border-top-color: #6D8CA0; - border-bottom-color: #6D8CA0; -} - -li.dropdown { - color: #2D2D2D; - font-weight: bold; -} - -.editInC9 { - font-size: 11px; - color: #657383; -} - -.editInC9 a { - color: #657383; - font-weight: normal; - position : relative; - top : -2px; -} - -.tabs { - padding-top: 14px; - /*border-bottom: 1px solid #848484;*/ - min-height : 27px; - padding-bottom : 5px; -} -.tabsSansBorder { - border: 0; -} -.tabs, .pills { - margin-bottom: 0; -} -.srolledHeader .members .tabs { - background-color: white; -} - -li.dropdown { - color: #2D2D2D; - font-weight: bold; -} - -.members .tabs .dropdown a, -.members .tabs a.menu:after, -.members .tabs .dropdown-toggle:after { - margin-right: 0; - margin-left: 6px; -} - -.memberLink a { - margin-left: 0 !important; -} -.menu-dropdown { - min-width : 105px; - max-height: 350px; - overflow: auto; - border-color : rgba(0, 0, 0, 0.1); -} -.topbar div > ul .menu-dropdown li a:hover, -.nav .menu-dropdown li a:hover, -.topbar div > ul .dropdown-menu li a:hover, -.nav .dropdown-menu li a:hover { - background-color: #ffffff; - color: #000000; -} - -.tabs a.menu:after, .tabs .dropdown-toggle:after { - margin-top: 13px; - line-height: 28px; -} -.open .menu, .dropdown.open .menu, .open .dropdown-toggle, .dropdown.open .dropdown-toggle { - background: transparent; - color: black; -/* font-weight: bold;*/ -} -#topSection .open .menu, #topSection .dropdown.open .menu, #topSection .open .dropdown-toggle, -#topSection .dropdown.open .dropdown-toggle { - color: #bfbfbf; -} - -.tabs > li { - font-weight: bold; -} - -.tabs > li > a { - border: none; - outline: none; - line-height: 28px; - font-size: 11px; - padding: 0 5px; -} -.tabs > li > a:hover { - color: #000000; - text-decoration: none; - background-color: transparent; - border: none; -} -.tabs > li, .pills > li { - float: right; -} -.topbar .dropdown-menu a, .dropdown-menu a { - font-size: 11px; -/* padding: 2px 12px;*/ - line-height: 14px; -} -.tabs .active > a, .tabs .active > a:hover { - color: #000000; - border: none; - cursor: default; -} -.tabs .menu-dropdown, .tabs .dropdown-menu { - border-radius: 0 0 6px 6px; - left: 10px; - width: 160px; -} -.srolled .tabs .menu-dropdown, .srolled .tabs .dropdown-menu { - top: 32px; -} -.dropdown-toggle { - color: #6D8CA0; -} - -ul.tabs .double ul, ul.tabs .triple ul, ul.tabs .quad ul{ - width:760px; - margin-bottom:20px; - overflow:hidden; - border-top:1px solid #ccc; -} -/*ul.tabs .double li, ul.tabs .triple li, ul.tabs .quad li{ - line-height:1.5em; - border-bottom:1px solid #ccc; - float:left; - display:inline; -}*/ - -/* - Center content (the "real stuff") -*/ - -#nonFooter { - padding-top: 40px; -} -#wrapper { - height: 100%; -} - -.content { - height: 100%; -} - -header.filler { - position: relative; - height: 40px; - width: 100%; -} - -/* -.container-fluid .row-fluid { - width: 1000px; - margin-left: auto; - margin-right: auto; -}*/ - -.divider { - height: 3px; - background-color: #BEDAEA; - margin-bottom: 3px; -} - -#sidebar h3 a, -#sidebar h3 a:hover { - color: #404040; -} - -#sidebarContainer { - padding-top: 20px; -} - -#mainContent { - margin-left: 30px; -} - -#documentation { - padding-top: 35px; - padding-bottom: 10px; -} - -#documentation article.article { - border-top: 1px solid #e9e9e9; - padding: 16px 10px 2px; - -webkit-transition: padding 0.2s; - -moz-transition: padding 0.2s; - -o-transition: padding 0.2s; -} - -#documentation h3.sectionHeader + article.article { - border-top: none; -} - -div#documentation article:last-child { - border-bottom: 1px solid #e9e9e9; - padding-bottom: 40px; -} -#documentation article.article.methodToggleOpen { - background: rgba(255, 255, 255, 0.5); - font-size: 13px; - line-height: 24px; - margin: 0 0 10px 0; -} - -#documentation article:first-child { - border:none; -} - -.site_logo { - display: block; - margin-left: auto; - margin-right: auto; -} -/* - Edit in Cloud9, sucka -*/ - -.snippet pre { - margin-bottom: 0; -} - -.snippet .toolbar { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - - text-align: right; - padding: 3px 10px; - margin-top : -1px; -} - -.snippet .filename, .snippet .toolbar { - font-family: Ubuntu, sans-serif; - font-size: 12px; - color: #EEE; -} - -.snippet .filename { - padding: 0 5px 2px 5px; - font-size: 10px; - background: rgba(230,230,230,0.5); - padding: 0 5px 2px 5px; - border-radius: 0 6px 0 6px; - margin : 1px; - position : absolute; - right : 0; - top : 0; -} - -.snippet .filename span{ - color : #666; -} - -.snippet .toolbar { - background-color: rgba(30,30,30,0.5); -} - -div.snippet { - margin-bottom: 18px; - position : relative; -} - -div.snippet a, div.toolbar a { - color: #FFF; -} - -/* - All about signatures -*/ - -.signatures { -/* width: 800px;*/ - margin-left: 20px; - margin-bottom: 5px; -} -.sideToggler { - padding-left: 20px; -} -ul.signatures ul { - list-style: none; - display: inline; -} - -li.signature { - list-style: none; -} - -.signature ul { - padding: 0; - margin: 0; -} - -.signature li { - display: inline; -} - -.signature ul.argument-types::before { - content: '→'; - margin: 0 5px; -} - -.signature li.argument-type::after { - content: '|'; - padding: 0 5px 0 5px; -} - -.signature li.argument-type:last-child:after { - content: ''; - padding: 0 5px 0 5px; -} - -.member-name { - color: #4397cd; - font-weight: bold; - text-decoration: none; - cursor: pointer; - padding-right: 3px; -} - -.signature-call { - cursor: pointer; -} - -#documentation .signature-call a { - color: #8e487e; -} - -.sigClassName { - display: none; -} - -.eventObjName { - font-style: italic; -} -.eventListenerStart, .eventListenerClose, .eventFunctionOpen, .eventFunctionClose { - color: #999999; -} -.eventMember { - padding-right: 0px; -} - -.metaInfo { - float: right; - z-index: 1; - position: relative; -} - -.chainable { - background-color: #0072bc; - color: #ffffff; -} - -.deprecated { - background-color: #f7941d; - color: #ffffff; -} - -.alias { - background-color: #6c951e; - color: #ffffff; -} - -.related-to { - background-color: #89289a; - color: #ffffff; - font-size: 10px; - padding: 2px 5px 3px; - text-transform: capitalize; -} - -.undocumented { - background-color: #B94A48; - color: #ffffff; -} - -#documentation .alias a, #documentation .related-to a { - color: #ffffff; - /* text-decoration: underline; */ -} -#documentation .alias a:hover, #documentation .related-to a:hover { - text-decoration: none; -} -.#documentation alias:hover, #documentation .related-to:hover { - opacity: 0.8; - cursor: pointer; -} -.memberContent .title { - -} -.memberContent .description { - position:relative; - /*top: -13px;*/ - display: none; -} -.snip-container .actions .toggle-plaintext label { - margin-top: 1px; - padding-top: 0; - text-align: left; -} -.snip-container .actions .toggle-plaintext input { - margin-top: 4px !important; -} -.snip-container label { - color: #ffffff; -} -.description h4 { - padding-top: 10px; - font-size: 18px; - line-height : 18px; -} - -.table-striped tbody tr:nth-child(odd) td, .table-striped tbody tr:nth-child(odd) th { - background-color: #F9F9F9; -} -.table-striped tbody tr:nth-child(even) td, .table-striped tbody tr:nth-child(even) th { - background-color: #fbfbfb; -} - -.argument-list { - margin-bottom : 13px; -} -.argName { - font-style: italic; -} - - -/* - Everyday I'm togglin' -*/ - -#documentation i.methodToggle { - cursor: pointer; - color: #9f9f9f; - padding-top: 2px; - float: left; -} -#documentation i.methodToggle.methodToggleHover { - text-shadow: 0 0 10px #4699d5; - color: #4699d5; -} -#documentation i.methodToggle.active { - text-shadow: 0 0 10px #4699d5; - color: #4699d5; - /* Safari */ - -webkit-transform: rotate(45deg); - - /* Firefox */ - -moz-transform: rotate(45deg); - - /* IE */ - -ms-transform: rotate(45deg); - - /* Opera */ - -o-transform: rotate(45deg); - padding-top: 9px; -} - -#documentation h3.sectionHeader { - line-height : 24px; -} - -div.method { - position: relative; -} - -.methodToggle a { - color: #fff; - border-bottom: 0px; - text-decoration: none; -} - -h3.methodToggle { - height : 13px; - width : 8px; - background-position : 0px 0px; - position: absolute; - top: -20px; - background-image : url(http://github.com/images/member-sprites.png); - background-color : transparent; - background-repeat : no-repeat; - overflow: hidden; - left: 0px; -} - -h3.methodToggleHover { - /* background-position : 0px -28px; */ -} - -h3.methodToggle.inactive { - top: 4px; -} - -h3.methodToggle.active { - top: 6px; - height : 13px; - width : 8px; - background-position : 0px -59px; -} - -.hidden { - display: none; - visibility: hidden; -} - -.hiddenSpan { - display: none; -} - -.ellipsis_description, .short_description { -/* width: 800px;*/ -} -.methodToggleOpen .ellipsis_description { - display: none; -} -.sideToggler .short_description, -.sideToggler .description{ - display: none; -} -.methodToggleOpen .short_description, -.methodToggleOpen .description { - display: block; -} -.description td p { - margin: 0; -} -/* - Footer? I hardly know her -*/ - -#footer { - width:100%; - background: #101010 url(http://github.com/images/dashed_back.png) repeat 0 0; - font-size: 12px; - color: white; - height: 40px; -} -#footer .footerInner { - padding-left: 300px; - margin-left: auto; - margin-right: auto; - min-height: 40px; -} -#footer .footer-text { - display: block; - font-size: 12px; - float: right; -} -#footer div.footerInner div.footer-text p { - font-size: 12px; - font-family: Arial; - line-height: 18px; - margin: 10px 15px 0px 1px; -} - -#footer a, #footer a:hover { - color: #8DD0FF; -} - -.logoText, .logoImg { - /*position: absolute;*/ - margin-bottom: 5px; -} - -.logoImg { - top: 40px; -} -.topbar div > ul .menu-dropdown li a:hover, -.nav .menu-dropdown li a:hover, -.topbar div > ul .dropdown-menu li a:hover, -.nav .dropdown-menu li a:hover { - background-color: #191919; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919)); - background-image: -moz-linear-gradient(top, #292929, #191919); - background-image: -ms-linear-gradient(top, #292929, #191919); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919)); - background-image: -webkit-linear-gradient(top, #292929, #191919); - background-image: -o-linear-gradient(top, #292929, #191919); - background-image: linear-gradient(top, #292929, #191919); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0); - color: #ffffff; -} - -.alert-message.block-message { - background: #fefaca; - border-color : #fefaca; - padding : 8px 14px 8px 14px; -} - -body .dsq-reply{ - margin-top : 10px; -} - -#disqus_thread{ - border-top : 1px solid #ddd; - margin-top : 30px; -} - -#disqus_thread h3, body #dsq-content h3 { - font-size : 12px; - margin : 0 0 20px 0; - line-height : 12px; -} -body #dsq-reply h3{ - font-size : 18px; - line-height : 18px; - margin : 15px 0 20px 0; -} - -#disqus_thread select{ - font-size : 11px; - height : 20px; - color : #444; -} - -#dsq-global-toolbar, #dsq-pagination, .dsq-trackback-url{ - display : none; -} diff --git a/api/resources/font/fontawesome-webfont.eot b/api/resources/font/fontawesome-webfont.eot deleted file mode 100644 index 89070c1e63c..00000000000 Binary files a/api/resources/font/fontawesome-webfont.eot and /dev/null differ diff --git a/api/resources/font/fontawesome-webfont.svg b/api/resources/font/fontawesome-webfont.svg deleted file mode 100644 index 1245f92c2ed..00000000000 --- a/api/resources/font/fontawesome-webfont.svg +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/resources/font/fontawesome-webfont.ttf b/api/resources/font/fontawesome-webfont.ttf deleted file mode 100644 index c17e9f8d100..00000000000 Binary files a/api/resources/font/fontawesome-webfont.ttf and /dev/null differ diff --git a/api/resources/font/fontawesome-webfont.woff b/api/resources/font/fontawesome-webfont.woff deleted file mode 100644 index 09f2469a1f7..00000000000 Binary files a/api/resources/font/fontawesome-webfont.woff and /dev/null differ diff --git a/api/resources/images/Ace_ERD.png b/api/resources/images/Ace_ERD.png deleted file mode 100644 index 78fb8dab6a2..00000000000 Binary files a/api/resources/images/Ace_ERD.png and /dev/null differ diff --git a/api/resources/images/ace_logo.png b/api/resources/images/ace_logo.png deleted file mode 100644 index 4dab4f66ebf..00000000000 Binary files a/api/resources/images/ace_logo.png and /dev/null differ diff --git a/api/resources/images/ace_logo_menu.png b/api/resources/images/ace_logo_menu.png deleted file mode 100644 index b011fadddde..00000000000 Binary files a/api/resources/images/ace_logo_menu.png and /dev/null differ diff --git a/api/resources/images/c9-log-footer.png b/api/resources/images/c9-log-footer.png deleted file mode 100644 index f3bcb4d790d..00000000000 Binary files a/api/resources/images/c9-log-footer.png and /dev/null differ diff --git a/api/resources/images/c9-sponsor.png b/api/resources/images/c9-sponsor.png deleted file mode 100644 index 599d3b49b07..00000000000 Binary files a/api/resources/images/c9-sponsor.png and /dev/null differ diff --git a/api/resources/images/cloud9-logo.png b/api/resources/images/cloud9-logo.png deleted file mode 100644 index 912524a9ee1..00000000000 Binary files a/api/resources/images/cloud9-logo.png and /dev/null differ diff --git a/api/resources/images/content-top.png b/api/resources/images/content-top.png deleted file mode 100644 index ec4ccad0c1d..00000000000 Binary files a/api/resources/images/content-top.png and /dev/null differ diff --git a/api/resources/images/content_bg.png b/api/resources/images/content_bg.png deleted file mode 100644 index 928f81e41ec..00000000000 Binary files a/api/resources/images/content_bg.png and /dev/null differ diff --git a/api/resources/images/content_top_bg.png b/api/resources/images/content_top_bg.png deleted file mode 100644 index 42039338c06..00000000000 Binary files a/api/resources/images/content_top_bg.png and /dev/null differ diff --git a/api/resources/images/dashed_back.png b/api/resources/images/dashed_back.png deleted file mode 100644 index c6ee9313f2d..00000000000 Binary files a/api/resources/images/dashed_back.png and /dev/null differ diff --git a/api/resources/images/footer-bg.png b/api/resources/images/footer-bg.png deleted file mode 100644 index 0d572c28099..00000000000 Binary files a/api/resources/images/footer-bg.png and /dev/null differ diff --git a/api/resources/images/main_bg.png b/api/resources/images/main_bg.png deleted file mode 100644 index f26aefc2af4..00000000000 Binary files a/api/resources/images/main_bg.png and /dev/null differ diff --git a/api/resources/images/member-sprites.png b/api/resources/images/member-sprites.png deleted file mode 100644 index 96b0520fd70..00000000000 Binary files a/api/resources/images/member-sprites.png and /dev/null differ diff --git a/api/resources/images/menu_disc.png b/api/resources/images/menu_disc.png deleted file mode 100644 index 1d3925b3f10..00000000000 Binary files a/api/resources/images/menu_disc.png and /dev/null differ diff --git a/api/resources/images/method_bg.png b/api/resources/images/method_bg.png deleted file mode 100644 index b018955737a..00000000000 Binary files a/api/resources/images/method_bg.png and /dev/null differ diff --git a/api/resources/images/scrolled-heading-shadow.png b/api/resources/images/scrolled-heading-shadow.png deleted file mode 100644 index aed814ee67f..00000000000 Binary files a/api/resources/images/scrolled-heading-shadow.png and /dev/null differ diff --git a/api/resources/images/sidebar-top-bg.png b/api/resources/images/sidebar-top-bg.png deleted file mode 100644 index c0a800e1f8a..00000000000 Binary files a/api/resources/images/sidebar-top-bg.png and /dev/null differ diff --git a/api/resources/images/sidebar_border.png b/api/resources/images/sidebar_border.png deleted file mode 100644 index ea6cd700be8..00000000000 Binary files a/api/resources/images/sidebar_border.png and /dev/null differ diff --git a/api/resources/images/swirl_divider.png b/api/resources/images/swirl_divider.png deleted file mode 100644 index f3e9f6c6af3..00000000000 Binary files a/api/resources/images/swirl_divider.png and /dev/null differ diff --git a/api/resources/javascripts/bbq.js b/api/resources/javascripts/bbq.js deleted file mode 100644 index bcbf24834ac..00000000000 --- a/api/resources/javascripts/bbq.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010 - * http://benalman.com/projects/jquery-bbq-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(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').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this); \ No newline at end of file diff --git a/api/resources/javascripts/bootstrap.js b/api/resources/javascripts/bootstrap.js deleted file mode 100644 index 79241e74e14..00000000000 --- a/api/resources/javascripts/bootstrap.js +++ /dev/null @@ -1,389 +0,0 @@ -/* ============================================================ - * bootstrap-dropdown.js v2.1.1 - * http://twitter.github.com/bootstrap/javascript.html#dropdowns - * ============================================================ - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* DROPDOWN CLASS DEFINITION - * ========================= */ - - var toggle = '[data-toggle=dropdown]' - , Dropdown = function (element) { - var $el = $(element).on('click.dropdown.data-api', this.toggle) - $('html').on('click.dropdown.data-api', function () { - $el.parent().removeClass('open') - }) - } - - Dropdown.prototype = { - - constructor: Dropdown - - , toggle: function (e) { - var $this = $(this) - , $parent - , isActive - - if ($this.is('.disabled, :disabled')) return - - $parent = getParent($this) - - isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - $parent.toggleClass('open') - $this.focus() - } - - return false - } - - , keydown: function (e) { - var $this - , $items - , $active - , $parent - , isActive - , index - - if (!/(38|40|27)/.test(e.keyCode)) return - - $this = $(this) - - e.preventDefault() - e.stopPropagation() - - if ($this.is('.disabled, :disabled')) return - - $parent = getParent($this) - - isActive = $parent.hasClass('open') - - if (!isActive || (isActive && e.keyCode == 27)) return $this.click() - - $items = $('[role=menu] li:not(.divider) a', $parent) - - if (!$items.length) return - - index = $items.index($items.filter(':focus')) - - if (e.keyCode == 38 && index > 0) index-- // up - if (e.keyCode == 40 && index < $items.length - 1) index++ // down - if (!~index) index = 0 - - $items - .eq(index) - .focus() - } - - } - - function clearMenus() { - getParent($(toggle)) - .removeClass('open') - } - - function getParent($this) { - var selector = $this.attr('data-target') - , $parent - - if (!selector) { - selector = $this.attr('href') - selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - $parent = $(selector) - $parent.length || ($parent = $this.parent()) - - return $parent - } - - - /* DROPDOWN PLUGIN DEFINITION - * ========================== */ - - $.fn.dropdown = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('dropdown') - if (!data) $this.data('dropdown', (data = new Dropdown(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.dropdown.Constructor = Dropdown - - - /* APPLY TO STANDARD DROPDOWN ELEMENTS - * =================================== */ - - $(function () { - $('html') - .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus) - $('body') - .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) - .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle) - .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) - }) - -}(window.jQuery); -/* ======================================================== - * bootstrap-tab.js v2.1.1 - * http://twitter.github.com/bootstrap/javascript.html#tabs - * ======================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* TAB CLASS DEFINITION - * ==================== */ - - var Tab = function (element) { - this.element = $(element) - } - - Tab.prototype = { - - constructor: Tab - - , show: function () { - var $this = this.element - , $ul = $this.closest('ul:not(.dropdown-menu)') - , selector = $this.attr('data-target') - , previous - , $target - , e - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - if ( $this.parent('li').hasClass('active') ) return - - previous = $ul.find('.active a').last()[0] - - e = $.Event('show', { - relatedTarget: previous - }) - - $this.trigger(e) - - if (e.isDefaultPrevented()) return - - $target = $(selector) - - this.activate($this.parent('li'), $ul) - this.activate($target, $target.parent(), function () { - $this.trigger({ - type: 'shown' - , relatedTarget: previous - }) - }) - } - - , activate: function ( element, container, callback) { - var $active = container.find('> .active') - , transition = callback - && $.support.transition - && $active.hasClass('fade') - - function next() { - $active - .removeClass('active') - .find('> .dropdown-menu > .active') - .removeClass('active') - - element.addClass('active') - - if (transition) { - element[0].offsetWidth // reflow for transition - element.addClass('in') - } else { - element.removeClass('fade') - } - - if ( element.parent('.dropdown-menu') ) { - element.closest('li.dropdown').addClass('active') - } - - callback && callback() - } - - transition ? - $active.one($.support.transition.end, next) : - next() - - $active.removeClass('in') - } - } - - - /* TAB PLUGIN DEFINITION - * ===================== */ - - $.fn.tab = function ( option ) { - return this.each(function () { - var $this = $(this) - , data = $this.data('tab') - if (!data) $this.data('tab', (data = new Tab(this))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.tab.Constructor = Tab - - - /* TAB DATA-API - * ============ */ - - $(function () { - $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { - e.preventDefault() - $(this).tab('show') - }) - }) - -}(window.jQuery); -/* ========================================================== - * bootstrap-affix.js v2.1.1 - * http://twitter.github.com/bootstrap/javascript.html#affix - * ========================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* AFFIX CLASS DEFINITION - * ====================== */ - - var Affix = function (element, options) { - this.options = $.extend({}, $.fn.affix.defaults, options) - this.$window = $(window).on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) - this.$element = $(element) - this.checkPosition() - } - - Affix.prototype.checkPosition = function () { - if (!this.$element.is(':visible')) return - - var scrollHeight = $(document).height() - , scrollTop = this.$window.scrollTop() - , position = this.$element.offset() - , offset = this.options.offset - , offsetBottom = offset.bottom - , offsetTop = offset.top - , reset = 'affix affix-top affix-bottom' - , affix - - if (typeof offset != 'object') offsetBottom = offsetTop = offset - if (typeof offsetTop == 'function') offsetTop = offset.top() - if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() - - affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? - false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? - 'bottom' : offsetTop != null && scrollTop <= offsetTop ? - 'top' : false - - if (this.affixed === affix) return - - this.affixed = affix - this.unpin = affix == 'bottom' ? position.top - scrollTop : null - - this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) - } - - - /* AFFIX PLUGIN DEFINITION - * ======================= */ - - $.fn.affix = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('affix') - , options = typeof option == 'object' && option - if (!data) $this.data('affix', (data = new Affix(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.affix.Constructor = Affix - - $.fn.affix.defaults = { - offset: 0 - } - - - /* AFFIX DATA-API - * ============== */ - - $(window).on('load', function () { - $('[data-spy="affix"]').each(function () { - var $spy = $(this) - , data = $spy.data() - - data.offset = data.offset || {} - - data.offsetBottom && (data.offset.bottom = data.offsetBottom) - data.offsetTop && (data.offset.top = data.offsetTop) - - $spy.affix(data) - }) - }) - - -}(window.jQuery); \ No newline at end of file diff --git a/api/resources/javascripts/clicker.js b/api/resources/javascripts/clicker.js deleted file mode 100644 index 90e7e12c813..00000000000 --- a/api/resources/javascripts/clicker.js +++ /dev/null @@ -1,69 +0,0 @@ -function setupClicker() { - // when hovering over arrow, add highlight (only if inactive) - $("i.methodToggle").hover(function () { - if (!$("i.methodToggle").hasClass('active')) - $(this).addClass("methodToggleHover"); - }, - function () { - $(this).removeClass("methodToggleHover"); - } - ); - - function handleClick(e, linkHref) { - //if (linkHref.indexOf("nav=api&api=") >= 0) - // return; - if (linkHref == "api") - return; - - e.preventDefault(); - - var dstElem; - if (linkHref) { - dstElem = $("article[id='" + linkHref + "']"); - } - - var $article = (dstElem || $(this)).closest('.article'), - $arrow = $('i.methodClicker', $article); - - if (!$article.hasClass('methodToggleOpen') || this.force) { - $article.addClass('methodToggleOpen'); - $arrow.removeClass('inactive').addClass('active'); - - if (!$arrow[0]) - return; - - var data = $arrow[0].id.replace(/^js_/, ""); - //var state = {}; - //state.section = data; - //$.bbq.pushState(state); - - scrollTo(null, data); - } - else { - $article.removeClass('methodToggleOpen'); - $arrow.removeClass('active').addClass('inactive'); - } - } - - function transformHash(e) { - // some bs to figure out link hash - var hashId = (e.srcElement ? e.srcElement.href : (e.hash || e.target.href)) || e.currentTarget.hash; - - handleClick(e, hashId.substring(hashId.indexOf("#") + 1)); - } - - // for the arrow - $("i.methodToggle").click(handleClick); - - // for the signature - $('.member-name').click(handleClick); - - // for the top dropdown - $('li.memberLink a').click(transformHash); - - //$('a[href^="#"]').click(transformHash); - - $('.related-to', '.metaInfo').click(function(){ - location.hash = $(this).find('a').attr('href').split('#')[1]; - }); -} \ No newline at end of file diff --git a/api/resources/javascripts/disqus-ext.js b/api/resources/javascripts/disqus-ext.js deleted file mode 100644 index 6bb7ff4ed63..00000000000 --- a/api/resources/javascripts/disqus-ext.js +++ /dev/null @@ -1,17 +0,0 @@ -function setupDisqus(href) { - var disqus_shortname = 'aceapi'; - - //var paths = window.location.pathname.split("/"); - //var fileName = paths[paths.length - 2] + "/" + paths[paths.length - 1]; - - //var disqus_identifier = fileName; - var disqus_identifier = href.substring(2); - - (function() { - if (document.getElementById("disqusScript") === null) { - var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; - dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js'; - (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); - } - })(); -} \ No newline at end of file diff --git a/api/resources/javascripts/jquery-scrollspy.js b/api/resources/javascripts/jquery-scrollspy.js deleted file mode 100644 index 71b4a3631b2..00000000000 --- a/api/resources/javascripts/jquery-scrollspy.js +++ /dev/null @@ -1,98 +0,0 @@ -/*! - * jQuery Scrollspy Plugin - * Author: @sxalexander - * Licensed under the MIT license - */ - - -;(function ( $, window, document, undefined ) { - - $.fn.extend({ - scrollspy: function ( options ) { - - var defaults = { - min: 0, - max: 0, - mode: 'vertical', - buffer: 0, - container: window, - onEnter: options.onEnter ? options.onEnter : [], - onLeave: options.onLeave ? options.onLeave : [], - onTick: options.onTick ? options.onTick : [] - } - - var options = $.extend( {}, defaults, options ); - - return this.each(function (i) { - - var element = this; - var o = options; - var $container = $(o.container); - var mode = o.mode; - var buffer = o.buffer; - var enters = leaves = 0; - var inside = false; - - /* add listener to container */ - $container.bind('scroll', function(e){ - var position = {top: $(this).scrollTop(), left: $(this).scrollLeft()}; - var xy = (mode == 'vertical') ? position.top + buffer : position.left + buffer; - var max = o.max; - var min = o.min; - - /* fix max */ - if($.isFunction(o.max)){ - max = o.max(); - } - - /* fix max */ - if($.isFunction(o.min)){ - min = o.min(); - } - - if(max == 0){ - max = (mode == 'vertical') ? $container.height() : $container.outerWidth() + $(element).outerWidth(); - } - - /* if we have reached the minimum bound but are below the max ... */ - if(xy >= o.min && xy <= max){ - /* trigger enter event */ - if(!inside){ - inside = true; - enters++; - - /* fire enter event */ - $(element).trigger('scrollEnter', {position: position}) - if($.isFunction(o.onEnter)){ - o.onEnter(element, position); - } - - } - - /* triger tick event */ - $(element).trigger('scrollTick', {position: position, inside: inside, enters: enters, leaves: leaves}) - if($.isFunction(o.onTick)){ - o.onTick(element, position, inside, enters, leaves); - } - }else{ - - if(inside){ - inside = false; - leaves++; - /* trigger leave event */ - $(element).trigger('scrollLeave', {position: position, leaves:leaves}) - - if($.isFunction(o.onLeave)){ - o.onLeave(element, position); - } - } - } - }); - - }); - } - - }) - - -})( jQuery, window ); diff --git a/api/resources/javascripts/jquery.collapse.js b/api/resources/javascripts/jquery.collapse.js deleted file mode 100644 index 427ee5fa002..00000000000 --- a/api/resources/javascripts/jquery.collapse.js +++ /dev/null @@ -1,151 +0,0 @@ -/*! - * Collapse plugin for jQuery - * http://github.com/danielstocks/jQuery-Collapse/ - * - * @author Daniel Stocks (http://webcloud.se) - * @version 0.9.1 - * @updated 17-AUG-2010 - * - * Copyright 2010, Daniel Stocks - * Released under the MIT, BSD, and GPL Licenses. - */ - -(function($) { - - // Use a cookie counter to allow multiple instances of the plugin - var cookieCounter = 0; - - $.fn.extend({ - collapse: function(options) { - - var defaults = { - head : "h3", - group : "div, ul", - cookieName : "collapse", - // Default function for showing content - show: function() { - this.show(); - }, - // Default function for hiding content - hide: function() { - this.hide(); - } - }; - var op = $.extend(defaults, options); - - // Default CSS classes - var active = "active", - inactive = "inactive"; - - return this.each(function() { - - // Increment coookie counter to ensure cookie name integrity - cookieCounter++; - var obj = $(this), - // Find all headers and wrap them in for accessibility. - sections = obj.find(op.head).wrapInner(''), - l = sections.length, - cookie = op.cookieName + "_" + cookieCounter; - // Locate all panels directly following a header - var panel = obj.find(op.head).map(function() { - var head = $(this) - if(!head.hasClass(active)) { - return head.next(op.group).hide()[0]; - } - return head.next(op.group)[0]; - }); - - // Bind event for showing content - obj.bind("show", function(e, bypass) { - var obj = $(e.target); - // ARIA attribute - obj.attr('aria-hidden', false) - .prev() - .removeClass(inactive) - .addClass(active); - // Bypass method for instant display - if(bypass) { - obj.show(); - } else { - op.show.call(obj); - } - }); - - // Bind event for hiding content - obj.bind("hide", function(e, bypass) { - var obj = $(e.target); - obj.attr('aria-hidden', true) - .prev() - .removeClass(active) - .addClass(inactive); - if(bypass) { - obj.hide(); - } else { - op.hide.call(obj); - } - }); - - // Look for existing cookies - if(cookieSupport) { - for (var c=0;c<=l;c++) { - var val = $.cookie(cookie + c); - // Show content if associating cookie is found - if ( val == c + "open" ) { - panel.eq(c).trigger('show', [true]); - // Hide content - } else if ( val == c + "closed") { - panel.eq(c).trigger('hide', [true]); - } - } - } - - // Delegate click event to show/hide content. - obj.bind("click", function(e) { - var t = $(e.target); - // Check if header was clicked - if(!t.is(op.head)) { - // What about link inside header. - if ( t.parent().is(op.head) ) { - t = t.parent(); - } else { - return; - } - e.preventDefault(); - } - // Figure out what position the clicked header has. - var num = sections.index(t), - cookieName = cookie + num, - cookieVal = num, - content = t.next(op.group); - // If content is already active, hide it. - if(t.hasClass(active)) { - content.trigger('hide'); - cookieVal += 'closed'; - if(cookieSupport) { - $.cookie(cookieName, cookieVal, { path: '/', expires: 10 }); - } - return; - } - // Otherwise show it. - content.trigger('show'); - cookieVal += 'open'; - if(cookieSupport) { - $.cookie(cookieName, cookieVal, { path: '/', expires: 10 }); - } - }); - }); - } - }); - - // Make sure can we eat cookies without getting into trouble. - var cookieSupport = (function() { - try { - $.cookie('x', 'x', { path: '/', expires: 10 }); - $.cookie('x', null); - } - catch(e) { - return false; - } - return true; - })(); -})(jQuery); \ No newline at end of file diff --git a/api/resources/javascripts/jquery.cookie.js b/api/resources/javascripts/jquery.cookie.js deleted file mode 100644 index 6df1faca25f..00000000000 --- a/api/resources/javascripts/jquery.cookie.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Cookie plugin - * - * Copyright (c) 2006 Klaus Hartl (stilbuero.de) - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - */ - -/** - * Create a cookie with the given name and value and other optional parameters. - * - * @example $.cookie('the_cookie', 'the_value'); - * @desc Set the value of a cookie. - * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); - * @desc Create a cookie with all available options. - * @example $.cookie('the_cookie', 'the_value'); - * @desc Create a session cookie. - * @example $.cookie('the_cookie', null); - * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain - * used when the cookie was set. - * - * @param String name The name of the cookie. - * @param String value The value of the cookie. - * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. - * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. - * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. - * If set to null or omitted, the cookie will be a session cookie and will not be retained - * when the the browser exits. - * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). - * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). - * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will - * require a secure protocol (like HTTPS). - * @type undefined - * - * @name $.cookie - * @cat Plugins/Cookie - * @author Klaus Hartl/klaus.hartl@stilbuero.de - */ - -/** - * Get the value of a cookie with the given name. - * - * @example $.cookie('the_cookie'); - * @desc Get the value of a cookie. - * - * @param String name The name of the cookie. - * @return The value of the cookie. - * @type String - * - * @name $.cookie - * @cat Plugins/Cookie - * @author Klaus Hartl/klaus.hartl@stilbuero.de - */ -jQuery.cookie = function(name, value, options) { - if (typeof value != 'undefined') { // name and value given, set cookie - options = options || {}; - if (value === null) { - value = ''; - options.expires = -1; - } - var expires = ''; - if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { - var date; - if (typeof options.expires == 'number') { - date = new Date(); - date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); - } else { - date = options.expires; - } - expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE - } - // CAUTION: Needed to parenthesize options.path and options.domain - // in the following expressions, otherwise they evaluate to undefined - // in the packed version for some reason... - var path = options.path ? '; path=' + (options.path) : ''; - var domain = options.domain ? '; domain=' + (options.domain) : ''; - var secure = options.secure ? '; secure' : ''; - document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); - } else { // only name given, get cookie - var cookieValue = null; - if (document.cookie && document.cookie != '') { - var cookies = document.cookie.split(';'); - for (var i = 0; i < cookies.length; i++) { - var cookie = jQuery.trim(cookies[i]); - // Does this cookie string begin with the name we want? - if (cookie.substring(0, name.length + 1) == (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; - } -}; \ No newline at end of file diff --git a/api/resources/javascripts/plugins.js b/api/resources/javascripts/plugins.js deleted file mode 100644 index efda459cd4b..00000000000 --- a/api/resources/javascripts/plugins.js +++ /dev/null @@ -1,13 +0,0 @@ -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))}}; -(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 -{console.log();return window.console;}catch(err){return window.console={};}})()); - -/* - * jQuery throttle / debounce - v1.1 - 3/7/2010 - * http://benalman.com/projects/jquery-throttle-debounce-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(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); diff --git a/api/resources/javascripts/prettify-extension.js b/api/resources/javascripts/prettify-extension.js deleted file mode 100644 index ca8458dc634..00000000000 --- a/api/resources/javascripts/prettify-extension.js +++ /dev/null @@ -1,24 +0,0 @@ -// Stolen from StackOverflow. Find all
 
-// elements on the page and add the "prettyprint" style. If at least one 
-// prettyprint element was found, call the Google Prettify prettyPrint() API.
-//http://sstatic.net/so/js/master.js?v=6523
-function styleCode() 
-{
-    if (typeof disableStyleCode != "undefined") 
-    {
-        return;
-    }
-
-    var a = false;
-
-    $("pre code").parent().each(function() 
-    {
-        if (!$(this).hasClass("prettyprint")) 
-        {
-            $(this).addClass("prettyprint");
-            a = true
-        }
-    });
-    
-    if (a) { prettyPrint() } 
-}
\ No newline at end of file
diff --git a/api/resources/javascripts/prettify.js b/api/resources/javascripts/prettify.js
deleted file mode 100644
index eef5ad7e6a0..00000000000
--- a/api/resources/javascripts/prettify.js
+++ /dev/null
@@ -1,28 +0,0 @@
-var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
-(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=
-[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(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;ci[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=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=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),
-l=[],p={},d=0,g=e.length;d=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])*(?:`|$))/,
-q,"'\"`"]):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]*/,
-q,"#"]));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,
-"");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),
-a.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}
-for(;!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=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*=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"],
-"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"],
-H=[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"],
-J=[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"+
-I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
-["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",
-/^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}),
-["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",
-hashComments: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=0){var k=k.match(g),f,b;if(b=
-!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 1010) sx = 1010 - document.documentElement.offsetWidth;
-    }
-    else sx = 0;
-
-    $('span.methodClicker, article.article, i.methodClicker').each(function () {
-        var a = $(this);
-        var constructorPos = a.attr("id").indexOf("new ");
-
-        var objName = a.attr("id");
-        if (constructorPos >= 0) {
-            objName = objName.substring(constructorPos + 4);
-            objName += ".new";
-        }
-
-        a.attr("id", objName);
-    });
-    
-    function showMethodContent() {
-        var locationHash = location.hash.replace(/^#/, '').replace(/\./g, '\\.');
-        var equalsPos = location.hash.indexOf("=");
-        
-        if (equalsPos >=0) {
-            locationHash = locationHash.substring(0, location.hash.indexOf("="));
-        }
-        
-        var $clickerEl = $('span#' + locationHash);
-        if ($clickerEl.length > 0 && $clickerEl.hasClass('methodClicker')) {
-            var p = $clickerEl.parent();
-            p[0].force = true;
-            p.trigger('click');
-            p[0].force = false;
-        }
-    }
-
-    if (location.hash.indexOf("section") >= 1) {
-        showMethodContent();
-        var data = location.hash;
-        scrollTo(null, data.substr(1));
-    }
-
-    window.onhashchange = function () {
-        showMethodContent();
-    }
-};
-
-function scrollTo(el, data) {
-    if (!data) {
-        data = el.getAttribute("data-id");
-        //location.hash = data;
-    }
-    var el = $("span#" + data.replace(/\./g, "\\."))[0];
-    if (!el) return;
-
-    var article = $(el).closest('.article')[0];
-
-    var top = article.offsetTop - 100;
-
-    if (document.body.scrollTop > top || document.body.scrollTop != top && document.body.scrollTop + (window.innerHeight || document.documentElement.offsetHeight) < top + article.offsetHeight) {
-        $('body').animate({
-            scrollTop: top
-        }, {
-            duration: 200,
-            easing: "swing"
-        });
-    }
-}
\ No newline at end of file
diff --git a/api/scrollbar.html b/api/scrollbar.html
deleted file mode 100644
index 5f3110602c4..00000000000
--- a/api/scrollbar.html
+++ /dev/null
@@ -1,261 +0,0 @@
-
-
-
-
-
-
-

ScrollBar -

- -
-
-
-
-

A set of methods for setting and retrieving the editor's scrollbar.

- -
-
-
-

Constructors

-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Creates a new ScrollBar. parent is the owner of the scroll bar.

- -
-

Creates a new ScrollBar. parent is the owner of the scroll bar.

- -

Arguments

parentDOMElement

Required. A DOM element

-
-
-
-
-
-
-

Events

-
-
-
-
-
    -
  • -
      -
    • ScrollBar.on("scroll", function(Object e))
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the scroll bar, well, scrolls.

- -
-

Emitted when the scroll bar, well, scrolls.

- -

Arguments

eObject

Required. Contains one property, "data", which indicates the current scroll top position

-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • ScrollBar.getWidth() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the width of the scroll bar.

- -
-

Returns the width of the scroll bar.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • ScrollBar.onScroll()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • ScrollBar.setHeight(Number height)
    • -
    -
      -
    -
  • -
-
-
-

Sets the height of the scroll bar, in pixels.

- -
-

Sets the height of the scroll bar, in pixels.

- -

Arguments

heightNumber

Required. The new height

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • ScrollBar.setInnerHeight(Number height)
    • -
    -
      -
    -
  • -
-
-
-

Sets the inner height of the scroll bar, in pixels.

- -
-

Sets the inner height of the scroll bar, in pixels.

- -

Arguments

heightNumber

Required. The new inner height

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • ScrollBar.setScrollTop(Number scrollTop)
    • -
    -
      -
    -
  • -
-
-
-

Sets the scroll top of the scroll bar.

- -
-

Sets the scroll top of the scroll bar.

- -

Arguments

scrollTopNumber

Required. The new scroll top

-
-
-
-
-
-
-
- - - - - -
-
\ No newline at end of file diff --git a/api/search.html b/api/search.html deleted file mode 100644 index 4b3d4ddff41..00000000000 --- a/api/search.html +++ /dev/null @@ -1,295 +0,0 @@ - -
-
-
-
-
-

Search -

- -
-
-
-
-

A class designed to handle all sorts of text searches within a Document.

- -
-
-
-

Constructors

-
-
-
-
-
    -
  • -
      -
    • new Search()
    • -
    -
      -
    -
  • -
-
-
-

Creates a new Search object. The following search options are available:

- -
-

Creates a new Search object. The following search options are available:

-
    -
  • needle: The string or regular expression you're looking for
  • -
  • backwards: Whether to search backwards from where cursor currently is. Defaults to false.
  • -
  • wrap: Whether to wrap the search back to the beginning when it hits the end. Defaults to false.
  • -
  • caseSensitive: Whether the search ought to be case-sensitive. Defaults to false.
  • -
  • wholeWord: Whether the search matches only on whole words. Defaults to false.
  • -
  • range: The Range to search within. Set this to null for the whole document
  • -
  • regExp: Whether the search is a regular expression or not. Defaults to false.
  • -
  • start: The starting Range or cursor position to begin the search
  • -
  • skipCurrent: Whether or not to include the current line in the search. Default to false.
  • -
- -
-
-
-
-
-

Methods

-
-
-
-
- -
-
-

Searches for options.needle. If found, this method returns the Range where the text first occurs. If options.backwards is true, the search goes backwards in the session.

- -
-

Searches for options.needle. If found, this method returns the Range where the text first occurs. If options.backwards is true, the search goes backwards in the session.

- -

Arguments

sessionEditSession

Required. The session to search with

-
-
-
-
-
-
-
-
-
-
- -
-
-

Searches for all occurances options.needle. If found, this method returns an array of Ranges where the text first occurs. If options.backwards is true, the search goes backwards in the session.

- -
-

Searches for all occurances options.needle. If found, this method returns an array of Ranges where the text first occurs. If options.backwards is true, the search goes backwards in the session.

- -

Arguments

sessionEditSession

Required. The session to search with

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Search.getOptions() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns an object containing all the search options.

- -
-

Returns an object containing all the search options.

- -
-
-
-
-
-
-
-
-
- -
-
-

Searches for options.needle in input, and, if found, replaces it with replacement.

- -
-

Searches for options.needle in input, and, if found, replaces it with replacement.

- -

Arguments

inputString

Required. The text to search in

-
replacementString

Required. The replacing text

-
    -
  • (String): If options.regExp is true, this function returns input with the replacement already made. Otherwise, this function just returns replacement.
    -If options.needle was not found, this function returns null.
  • -
-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    • Chainable
    • -
    -
  • -
-
-
-

Sets the search options via the options parameter.

- -
-

Sets the search options via the options parameter.

- -

Arguments

optionsObject

Required. An object containing all the new search properties

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Search.setOptions()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
- - - - - -
-
diff --git a/api/selection.html b/api/selection.html deleted file mode 100644 index 4da8f771b3b..00000000000 --- a/api/selection.html +++ /dev/null @@ -1,1781 +0,0 @@ - -
-
-
- -
-
-

Contains the cursor position and the text selection of an edit session.

-

The row/columns used in the selection are in document coordinates representing the coordinates as they appear in the document before applying soft wrap and folding.

- -
-
-
-

Constructors

-
-
-
-
- -
-
-

Creates a new Selection object.

- -
-

Creates a new Selection object.

- -

Arguments

sessionEditSession

Required. The session to use

-
-
-
-
-
-
-

Events

-
-
-
-
-
    -
  • -
      -
    • Selection.on("changeCursor", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the cursor position changes.

- -
-

Emitted when the cursor position changes.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.on("changeSelection", function())
    • -
    -
      -
    -
  • -
-
-
-

Emitted when the cursor selection changes.

- -
-

Emitted when the cursor selection changes.

- -
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • Selection.addRange(Range range, Boolean $blockChangeEvents)
    • -
    -
      -
    -
  • -
-
-
-

Adds a range to a selection by entering multiselect mode, if necessary.

- -
-

Adds a range to a selection by entering multiselect mode, if necessary.

- -

Arguments

rangeRange

Required. The new range to add

-
$blockChangeEventsBoolean

Required. Whether or not to block changing events

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.clearSelection()
    • -
    -
      -
    -
  • -
-
-
-

Empties the selection (by de-selecting it). This function also emits the 'changeSelection' event.

- -
-

Empties the selection (by de-selecting it). This function also emits the 'changeSelection' event.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.detach()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.fromOrientedRange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.getAllRanges() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns a concatenation of all the ranges.

- -
-

Returns a concatenation of all the ranges.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.getCursor() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Gets the current position of the cursor.

- -
-

Gets the current position of the cursor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.getLineRange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.getRange() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the Range for the selected text.

- -
-

Returns the Range for the selected text.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.getSelectionAnchor() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns an object containing the row and column of the calling selection anchor.

- -
-

Returns an object containing the row and column of the calling selection anchor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.getSelectionLead() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns an object containing the row and column of the calling selection lead.

- -
-

Returns an object containing the row and column of the calling selection lead.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Moves the selection to highlight the entire word.

- -
-

Moves the selection to highlight the entire word.

- -

Arguments

rowObject

Required.

-
columnObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.isBackwards() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the selection is going backwards in the document.

- -
-

Returns true if the selection is going backwards in the document.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.isEmpty() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the selection is empty.

- -
-

Returns true if the selection is empty.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.isMultiLine() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the selection is a multi-line.

- -
-

Returns true if the selection is a multi-line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.mergeOverlappingRanges()
    • -
    -
      -
    -
  • -
-
-
-

Merges overlapping ranges ensuring consistency after changes

- -
-

Merges overlapping ranges ensuring consistency after changes

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Moves the cursor to position indicated by the parameters. Negative numbers move the cursor backwards in the document.

- -
-

Moves the cursor to position indicated by the parameters. Negative numbers move the cursor backwards in the document.

- -

Arguments

rowsNumber

Required. The number of rows to move by

-
charsNumber

Required. The number of characters to move by

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorDown()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor down one row.

- -
-

Moves the cursor down one row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorFileEnd()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the end of the file.

- -
-

Moves the cursor to the end of the file.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorFileStart()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the start of the file.

- -
-

Moves the cursor to the start of the file.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorLeft()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor left one column.

- -
-

Moves the cursor left one column.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorLineEnd()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the end of the line.

- -
-

Moves the cursor to the end of the line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorLineStart()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the start of the line.

- -
-

Moves the cursor to the start of the line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorLongWordLeft()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the word on the left.

- -
-

Moves the cursor to the word on the left.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorLongWordRight()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor to the word on the right.

- -
-

Moves the cursor to the word on the right.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorRight()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor right one column.

- -
-

Moves the cursor right one column.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorShortWordLeft()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorShortWordRight()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-

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.

- -
-

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.

- -

Arguments

rowNumber

Required. The row to move to

-
columnNumber

Required. The column to move to

-
keepDesiredColumnBoolean

Required. If true, the cursor move does not respect the previous column

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorToPosition(Object position)
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection to the position indicated by its row and column.

- -
-

Moves the selection to the position indicated by its row and column.

- -

Arguments

positionObject

Required. The position to move to

-
-
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Moves the cursor to the screen position indicated by row and column. If preventUpdateDesiredColumn is true, then the cursor stays in the same column position as its original point.

- -
-

Moves the cursor to the screen position indicated by row and column. If preventUpdateDesiredColumn is true, then the cursor stays in the same column position as its original point.

- -

Arguments

rowNumber

Required. The row to move to

-
columnNumber

Required. The column to move to

-
keepDesiredColumnBoolean

Required. If true, the cursor move does not respect the previous column

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorUp()
    • -
    -
      -
    -
  • -
-
-
-

Moves the cursor up one row.

- -
-

Moves the cursor up one row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorWordLeft()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.moveCursorWordRight()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.rectangularRangeBlock(Cursor screenCursor, Anchor screenAnchor, Boolean includeEmptyLines) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Gets list of ranges composing rectangular block on the screen

- -
-

Gets list of ranges composing rectangular block on the screen

- -

Arguments

screenCursorCursor

Required. The cursor to use

-
screenAnchorAnchor

Required. The anchor to use

-
includeEmptyLinesBoolean

Required. If true, this includes ranges inside the block which are empty due to clipping

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectAll()
    • -
    -
      -
    -
  • -
-
-
-

Selects all the text in the document.

- -
-

Selects all the text in the document.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectAWord()
    • -
    -
      -
    -
  • -
-
-
-

Selects a word, including its right whitespace.

- -
-

Selects a word, including its right whitespace.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectDown()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection down one row.

- -
-

Moves the selection down one row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectFileEnd()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection to the end of the file.

- -
-

Moves the selection to the end of the file.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectFileStart()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection to the start of the file.

- -
-

Moves the selection to the start of the file.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectLeft()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection left one column.

- -
-

Moves the selection left one column.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectLine()
    • -
    -
      -
    -
  • -
-
-
-

Selects the entire line.

- -
-

Selects the entire line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectLineEnd()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection to the end of the current line.

- -
-

Moves the selection to the end of the current line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectLineStart()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection to the beginning of the current line.

- -
-

Moves the selection to the beginning of the current line.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectRight()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection right one column.

- -
-

Moves the selection right one column.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Moves the selection cursor to the indicated row and column.

- -
-

Moves the selection cursor to the indicated row and column.

- -

Arguments

rowNumber

Required. The row to select to

-
columnNumber

Required. The column to select to

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectToPosition(Object pos)
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection cursor to the row and column indicated by pos.

- -
-

Moves the selection cursor to the row and column indicated by pos.

- -

Arguments

posObject

Required. An object containing the row and column

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectUp()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection up one row.

- -
-

Moves the selection up one row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectWord()
    • -
    -
      -
    -
  • -
-
-
-

Selects an entire word boundary.

- -
-

Selects an entire word boundary.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectWordLeft()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection to the first word on the left.

- -
-

Moves the selection to the first word on the left.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.selectWordRight()
    • -
    -
      -
    -
  • -
-
-
-

Moves the selection to the first word on the right.

- -
-

Moves the selection to the first word on the right.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.setSelectionAnchor(Number row, Number column)
    • -
    -
      -
    -
  • -
-
-
-

Sets the row and column position of the anchor. This function also emits the 'changeSelection' event.

- -
-

Sets the row and column position of the anchor. This function also emits the 'changeSelection' event.

- -

Arguments

rowNumber

Required. The new row

-
columnNumber

Required. The new column

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.setSelectionRange(Range range, Boolean reverse)
    • -
    -
      -
    -
  • -
-
-
-

Sets the selection to the provided range.

- -
-

Sets the selection to the provided range.

- -

Arguments

rangeRange

Required. The range of text to select

-
reverseBoolean

Required. Indicates if the range should go backwards (true) or not

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.shiftSelection(Number columns)
    • -
    -
      -
    -
  • -
-
-
-

Shifts the selection up (or down, if isBackwards() is true) the given number of columns.

- -
-

Shifts the selection up (or down, if isBackwards() is true) the given number of columns.

- -

Arguments

columnsNumber

Required. The number of columns to shift by

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.splitIntoLines()
    • -
    -
      -
    -
  • -
-
-
-

Splits all the ranges into lines.

- -
-

Splits all the ranges into lines.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.substractPoint(Range pos)
    • -
    -
      -
    -
  • -
-
-
-

Removes a Range containing pos (if it exists).

- -
-

Removes a Range containing pos (if it exists).

- -

Arguments

posRange

Required. The position to remove, as a {row, column} object

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.toggleBlockSelection()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.toOrientedRange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Selection.toSingleRange()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
- - - - - -
-
diff --git a/api/split.html b/api/split.html deleted file mode 100644 index fd75edceb1c..00000000000 --- a/api/split.html +++ /dev/null @@ -1,640 +0,0 @@ - -
-
-
-
-
-

Split -

- -
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • Split.blur()
    • -
    -
      -
    -
  • -
-
-
-

Blurs the current editor.

- -
-

Blurs the current editor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.execute()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.focus()
    • -
    -
      -
    -
  • -
-
-
-

Focuses the current editor.

- -
-

Focuses the current editor.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-

Arguments

callbackFunction

Required. A callback function to execute

-
scopeString

Required. The default scope for the callback

-

Executes callback on all of the available editors.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.getCurrentEditor() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current editor.

- -
-

Returns the current editor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.getEditor(Number idx)
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-

Arguments

idxNumber

Required. The index of the editor you want

-

Returns the editor identified by the index idx.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.getOrientation() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the orientation.

- -
-

Returns the orientation.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.getSplits() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the number of splits.

- -
-

Returns the number of splits.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.hasRedo()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.hasUndo()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.redo()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.reset()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.resize()
    • -
    -
      -
    -
  • -
-
-
-

Resizes the editor.

- -
-

Resizes the editor.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.setFontSize(Number size)
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-

Arguments

sizeNumber

Required. The new font size

-

Sets the font size, in pixels, for all the available editors.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.setKeyboardHandler(String keybinding)
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-

Arguments

keybindingString

Required. Sets the keyboard handler for the editor.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.setOrientation(Number orientation)
    • -
    -
      -
    -
  • -
-
-
-

Sets the orientation.

- -
-

Sets the orientation.

- -

Arguments

orientationNumber

Required. The new orientation value

-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-

Arguments

sessionEditSession

Required. The new edit session

-
idxNumber

Required. The editor's index you're interested in

-

Sets a new EditSession for the indicated editor.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.setSplits()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.setTheme(String theme)
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-

Arguments

themeString

Required. The name of the theme to set

-

Sets a theme for each of the available editors.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.undo()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • Split.UndoManagerProxy()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
- - - - - -
-
\ No newline at end of file diff --git a/api/token_iterator.html b/api/token_iterator.html deleted file mode 100644 index 0252712fdf2..00000000000 --- a/api/token_iterator.html +++ /dev/null @@ -1,248 +0,0 @@ - -
-
-
-
-
-

TokenIterator -

- -
-
-
-
-

This class provides an essay way to treat the document as a stream of tokens, and provides methods to iterate over these tokens.

- -
-
-
-

Constructors

-
-
-
-
- -
-
-

Creates a new token iterator object. The initial token index is set to the provided row and column coordinates.

- -
-

Creates a new token iterator object. The initial token index is set to the provided row and column coordinates.

- -

Arguments

sessionEditSession

Required. The session to associate with

-
initialRowNumber

Required. The row to start the tokenizing at

-
initialColumnNumber

Required. The column to start the tokenizing at

-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • TokenIterator.getCurrentToken() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current tokenized string.

- -
-

Returns the current tokenized string.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • TokenIterator.getCurrentTokenColumn() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current column.

- -
-

Returns the current column.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • TokenIterator.getCurrentTokenRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the current row.

- -
-

Returns the current row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • TokenIterator.stepBackward() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Tokenizes all the items from the current point to the row prior in the document.

- -
-

Tokenizes all the items from the current point to the row prior in the document.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • TokenIterator.stepForward() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Tokenizes all the items from the current point until the next row in the document. If the current point is at the end of the file, this function returns null. Otherwise, it returns the tokenized string.

- -
-

Tokenizes all the items from the current point until the next row in the document. If the current point is at the end of the file, this function returns null. Otherwise, it returns the tokenized string.

- -
-
-
-
-
-
- - - - - -
-
diff --git a/api/tokenizer.html b/api/tokenizer.html deleted file mode 100644 index b45bd58da21..00000000000 --- a/api/tokenizer.html +++ /dev/null @@ -1,122 +0,0 @@ - -
-
-
-
-
-

Tokenizer -

- -
-
- -

Constructors

-
-
-
-
- -
-
-

Constructs a new tokenizer based on the given rules and flags.

- -
-

Constructs a new tokenizer based on the given rules and flags.

- -

Arguments

rulesObject

Required. The highlighting rules

-
flagString

Required. Any additional regular expression flags to pass (like "i" for case insensitive)

-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns an object containing two properties: tokens, which contains all the tokens; and state, the current state.

- -
-

Returns an object containing two properties: tokens, which contains all the tokens; and state, the current state.

- -

Arguments

lineObject

Required.

-
startStateObject

Required.

-
-
-
-
-
-
-
- - - - - -
-
\ No newline at end of file diff --git a/api/undomanager.html b/api/undomanager.html deleted file mode 100644 index ea43a7fbc58..00000000000 --- a/api/undomanager.html +++ /dev/null @@ -1,271 +0,0 @@ - -
-
-
-
-
-

UndoManager -

- -
-
-
-
-

This object maintains the undo stack for an EditSession.

- -
-
-
-

Constructors

-
-
-
-
-
    -
  • -
      -
    • new UndoManager()
    • -
    -
      -
    -
  • -
-
-
-

Resets the current undo state and creates a new UndoManager.

- -
-

Resets the current undo state and creates a new UndoManager.

- -
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • UndoManager.execute(Object options)
    • -
    -
      -
    -
  • -
-
-
-

Provides a means for implementing your own undo manager. options has one property, args, an Array, with two elements:

- -
-

Provides a means for implementing your own undo manager. options has one property, args, an Array, with two elements:

-
    -
  • args[0] is an array of deltas
  • -
  • args[1] is the document to associate with
  • -
- -

Arguments

optionsObject

Required. Contains additional properties

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • UndoManager.hasRedo() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if there are redo operations left to perform.

- -
-

Returns true if there are redo operations left to perform.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • UndoManager.hasUndo() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if there are undo operations left to perform.

- -
-

Returns true if there are undo operations left to perform.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • UndoManager.redo(Boolean dontSelect)
    • -
    -
      -
    -
  • -
-
-
-

Perform a redo operation on the document, reimplementing the last change.

- -
-

Perform a redo operation on the document, reimplementing the last change.

- -

Arguments

dontSelectBoolean

Required. If true, doesn't select the range of where the change occurred

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • UndoManager.reset()
    • -
    -
      -
    -
  • -
-
-
-

Destroys the stack of undo and redo redo operations.

- -
-

Destroys the stack of undo and redo redo operations.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Perform an undo operation on the document, reverting the last change.

- -
-

Perform an undo operation on the document, reverting the last change.

- -

Arguments

dontSelectBoolean

Required. If true, doesn't select the range of where the change occurred

-
-
-
-
-
-
-
- - - - - -
-
diff --git a/api/virtual_renderer.html b/api/virtual_renderer.html deleted file mode 100644 index abdfecc8756..00000000000 --- a/api/virtual_renderer.html +++ /dev/null @@ -1,2190 +0,0 @@ - -
-
-
-
-
-

VirtualRenderer -

- -
-
-
-
-

The class that is responsible for drawing everything you see on the screen!

- -
-
-
-

Constructors

-
-
-
-
- -
-
-

Constructs a new VirtualRenderer within the container specified, applying the given theme.

- -
-

Constructs a new VirtualRenderer within the container specified, applying the given theme.

- -

Arguments

containerDOMElement

Required. The root element of the editor

-
themeString

Required. The starting theme

-
-
-
-
-
-
-

Methods

-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer._loadTheme()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.addGutterDecoration(Object row, Object className)
    • -
    -
      -
    -
  • -
-
-
-

Deprecated; (moved to EditSession)

- -
-

Deprecated; (moved to EditSession)

- -

Arguments

rowObject

Required.

-
classNameObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.adjustWrapLimit()
    • -
    -
      -
    -
  • -
-
-
-

Adjusts the wrap limit, which is the number of characters that can fit within the width of the edit area on screen.

- -
-

Adjusts the wrap limit, which is the number of characters that can fit within the width of the edit area on screen.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.alignCursor()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.animateScrolling()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.destroy()
    • -
    -
      -
    -
  • -
-
-
-

Destroys the text and cursor layers for this renderer.

- -
-

Destroys the text and cursor layers for this renderer.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getAnimatedScroll() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns whether an animated scroll happens or not.

- -
-

Returns whether an animated scroll happens or not.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getContainerElement() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the root element containing this renderer.

- -
-

Returns the root element containing this renderer.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getDisplayIndentGuides()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getFadeFoldWidgets()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getFirstFullyVisibleRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

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.

- -
-

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.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getFirstVisibleRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the index of the first visible row.

- -
-

Returns the index of the first visible row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getHighlightGutterLine()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getHScrollBarAlwaysVisible() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns whether the horizontal scrollbar is set to be always visible.

- -
-

Returns whether the horizontal scrollbar is set to be always visible.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getLastFullyVisibleRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

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.

- -
-

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.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getLastVisibleRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the index of the last visible row.

- -
-

Returns the index of the last visible row.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getMouseEventTarget() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the element that the mouse events are attached to

- -
-

Returns the element that the mouse events are attached to

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getPrintMarginColumn() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns whether the print margin column is being shown or not.

- -
-

Returns whether the print margin column is being shown or not.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getScrollBottomRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the last visible row, regardless of whether it's fully visible or not.

- -
-

Returns the last visible row, regardless of whether it's fully visible or not.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getScrollLeft() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the value of the distance between the left of the editor and the leftmost part of the visible content.

- -
-

Returns the value of the distance between the left of the editor and the leftmost part of the visible content.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getScrollTop() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the value of the distance between the top of the editor and the topmost part of the visible content.

- -
-

Returns the value of the distance between the top of the editor and the topmost part of the visible content.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getScrollTopRow() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the first visible row, regardless of whether it's fully visible or not.

- -
-

Returns the first visible row, regardless of whether it's fully visible or not.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getShowGutter() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns true if the gutter is being shown.

- -
-

Returns true if the gutter is being shown.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getShowInvisibles() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns whether invisible characters are being shown or not.

- -
-

Returns whether invisible characters are being shown or not.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getShowPrintMargin() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns whether the print margin is being shown or not.

- -
-

Returns whether the print margin is being shown or not.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getTextAreaContainer() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the element to which the hidden text area is added.

- -
-

Returns the element to which the hidden text area is added.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.getTheme() -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Returns the path of the current theme.

- -
-

Returns the path of the current theme.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.hideComposition()
    • -
    -
      -
    -
  • -
-
-
-

Hides the current composition.

- -
-

Hides the current composition.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.hideCursor()
    • -
    -
      -
    -
  • -
-
-
-

Hides the cursor icon.

- -
-

Hides the cursor icon.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns true if you can still scroll by either parameter; in other words, you haven't reached the end of the file or line.

- -
-

Returns true if you can still scroll by either parameter; in other words, you haven't reached the end of the file or line.

- -

Arguments

deltaXNumber

Required. The x value to scroll by

-
deltaYNumber

Required. The y value to scroll by

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.onChangeTabSize()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.onGutterResize()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-

Triggers a resize of the editor.

- -
-

Triggers a resize of the editor.

- -

Arguments

forceBoolean

Required. If true, recomputes the size, even if the height and width haven't changed

-
gutterWidthNumber

Required. The width of the gutter in pixels

-
widthNumber

Required. The width of the editor in pixels

-
heightNumber

Required. The height of the editor, in pixels

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.pixelToScreenCoordinates()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.removeGutterDecoration(Object row, Object className)
    • -
    -
      -
    -
  • -
-
-
-

Deprecated; (moved to EditSession)

- -
-

Deprecated; (moved to EditSession)

- -

Arguments

rowObject

Required.

-
classNameObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.screenToTextCoordinates()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.scrollBy(Number deltaX, Number deltaY)
    • -
    -
      -
    -
  • -
-
-
-

Scrolls the editor across both x- and y-axes.

- -
-

Scrolls the editor across both x- and y-axes.

- -

Arguments

deltaXNumber

Required. The x value to scroll by

-
deltaYNumber

Required. The y value to scroll by

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.scrollCursorIntoView(Object cursor, Object offset)
    • -
    -
      -
    -
  • -
-
-
-

Scrolls the cursor into the first visible area of the editor

- -
-

Scrolls the cursor into the first visible area of the editor

- -

Arguments

cursorObject

Required.

-
offsetObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.scrollSelectionIntoView()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-

Gracefully scrolls the editor to the row indicated.

- -
-

Gracefully scrolls the editor to the row indicated.

- -

Arguments

lineNumber

Required. A line number

-
centerBoolean

Required. If true, centers the editor the to indicated line

-
animateBoolean

Required. If true animates scrolling

-
callbackFunction

Required. Function to be called after the animation has finished

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.scrollToRow(Number row)
    • -
    -
      -
    -
  • -
-
-
-

Gracefully scrolls from the top of the editor to the row indicated.

- -
-

Gracefully scrolls from the top of the editor to the row indicated.

- -

Arguments

rowNumber

Required. A row id

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.scrollToX(Number scrollLeft) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Scrolls the editor across the x-axis to the pixel indicated.

- -
-

Scrolls the editor across the x-axis to the pixel indicated.

- -

Arguments

scrollLeftNumber

Required. The position to scroll to

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.scrollToY(Number scrollTop) -
    • - -
    • -
    -
      -
    -
  • -
-
-
-

Scrolls the editor to the y pixel indicated.

- -
-

Scrolls the editor to the y pixel indicated.

- -

Arguments

scrollTopNumber

Required. The position to scroll to

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setAnimatedScroll(Boolean shouldAnimate)
    • -
    -
      -
    -
  • -
-
-
-

Identifies whether you want to have an animated scroll or not.

- -
-

Identifies whether you want to have an animated scroll or not.

- -

Arguments

shouldAnimateBoolean

Required. Set to true to show animated scrolls

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setAnnotations(Array annotations)
    • -
    -
      -
    -
  • -
-
-
-

Sets annotations for the gutter.

- -
-

Sets annotations for the gutter.

- -

Arguments

annotationsArray

Required. An array containing annotations

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setCompositionText(String text)
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-

Arguments

textString

Required. A string of text to use

-

Sets the inner text of the current composition to text.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setDisplayIndentGuides()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setFadeFoldWidgets()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setHighlightGutterLine()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setHScrollBarAlwaysVisible(Boolean alwaysVisible)
    • -
    -
      -
    -
  • -
-
-
-

Identifies whether you want to show the horizontal scrollbar or not.

- -
-

Identifies whether you want to show the horizontal scrollbar or not.

- -

Arguments

alwaysVisibleBoolean

Required. Set to true to make the horizontal scroll bar visible

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setPadding(Number padding)
    • -
    -
      -
    -
  • -
-
-
-

Sets the padding for all the layers.

- -
-

Sets the padding for all the layers.

- -

Arguments

paddingNumber

Required. A new padding value (in pixels)

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setPrintMarginColumn(Boolean showPrintMargin)
    • -
    -
      -
    -
  • -
-
-
-

Identifies whether you want to show the print margin column or not.

- -
-

Identifies whether you want to show the print margin column or not.

- -

Arguments

showPrintMarginBoolean

Required. Set to true to show the print margin column

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setSession(Object session)
    • -
    -
      -
    -
  • -
-
-
-

Associates the renderer with an EditSession.

- -
-

Associates the renderer with an EditSession.

- -

Arguments

sessionObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setShowGutter(Boolean show)
    • -
    -
      -
    -
  • -
-
-
-

Identifies whether you want to show the gutter or not.

- -
-

Identifies whether you want to show the gutter or not.

- -

Arguments

showBoolean

Required. Set to true to show the gutter

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setShowInvisibles(Boolean showInvisibles)
    • -
    -
      -
    -
  • -
-
-
-

Identifies whether you want to show invisible characters or not.

- -
-

Identifies whether you want to show invisible characters or not.

- -

Arguments

showInvisiblesBoolean

Required. Set to true to show invisibles

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setShowPrintMargin(Boolean showPrintMargin)
    • -
    -
      -
    -
  • -
-
-
-

Identifies whether you want to show the print margin or not.

- -
-

Identifies whether you want to show the print margin or not.

- -

Arguments

showPrintMarginBoolean

Required. Set to true to show the print margin

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setStyle()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.setTheme(String theme)
    • -
    -
      -
    -
  • -
-
-
-

Sets a new theme for the editor. theme should exist, and be a directory path, like ace/theme/textmate.

- -
-

Sets a new theme for the editor. theme should exist, and be a directory path, like ace/theme/textmate.

- -

Arguments

themeString

Required. The path to a theme

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.showCursor()
    • -
    -
      -
    -
  • -
-
-
-

Shows the cursor icon.

- -
-

Shows the cursor icon.

- -
-
-
-
-
-
-
-
-
-
    -
  • - -
      -
    -
  • -
-
-
-

Returns an object containing the pageX and pageY coordinates of the document position.

- -
-

Returns an object containing the pageX and pageY coordinates of the document position.

- -

Arguments

rowNumber

Required. The document row position

-
columnNumber

Required. The document column position

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.unsetStyle(String style)
    • -
    -
      -
    -
  • -
-
-
-

Removes the class style from the editor.

- -
-

Removes the class style from the editor.

- -

Arguments

styleString

Required. A class name

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateBackMarkers()
    • -
    -
      -
    -
  • -
-
-
-

Schedules an update to all the back markers in the document.

- -
-

Schedules an update to all the back markers in the document.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateBreakpoints(Object rows)
    • -
    -
      -
    -
  • -
-
-
-

Redraw breakpoints.

- -
-

Redraw breakpoints.

- -

Arguments

rowsObject

Required.

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateCharacterSize()
    • -
    -
      -
    • Undocumented
    • -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateCursor()
    • -
    -
      -
    -
  • -
-
-
-

Updates the cursor icon.

- -
-

Updates the cursor icon.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateFontSize()
    • -
    -
      -
    -
  • -
-
-
-

Updates the font size.

- -
-

Updates the font size.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateFrontMarkers()
    • -
    -
      -
    -
  • -
-
-
-

Schedules an update to all the front markers in the document.

- -
-

Schedules an update to all the front markers in the document.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateFull(Boolean force)
    • -
    -
      -
    -
  • -
-
-
-

Triggers a full update of all the layers, for all the rows.

- -
-

Triggers a full update of all the layers, for all the rows.

- -

Arguments

forceBoolean

Required. If true, forces the changes through

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateLines(Number firstRow, Number lastRow)
    • -
    -
      -
    -
  • -
-
-
-

Triggers a partial update of the text, from the range given by the two parameters.

- -
-

Triggers a partial update of the text, from the range given by the two parameters.

- -

Arguments

firstRowNumber

Required. The first row to update

-
lastRowNumber

Required. The last row to update

-
-
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.updateText()
    • -
    -
      -
    -
  • -
-
-
-

Triggers a full update of the text, for all the rows.

- -
-

Triggers a full update of the text, for all the rows.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.visualizeBlur()
    • -
    -
      -
    -
  • -
-
-
-

Blurs the current container.

- -
-

Blurs the current container.

- -
-
-
-
-
-
-
-
-
-
    -
  • -
      -
    • VirtualRenderer.visualizeFocus()
    • -
    -
      -
    -
  • -
-
-
-

Focuses the current container.

- -
-

Focuses the current container.

- -
-
-
-
-
-
- - - - - -
-
diff --git a/build b/build index c915483e909..56a46777e92 160000 --- a/build +++ b/build @@ -1 +1 @@ -Subproject commit c915483e909bc1b3061cabaaf932f796c723226b +Subproject commit 56a46777e92abd648dce1c29069c13a74480f9a5 diff --git a/demo/autoresize.html b/demo/autoresize.html index 7b7fbf48b74..00f8f1b7fb6 100644 --- a/demo/autoresize.html +++ b/demo/autoresize.html @@ -9,12 +9,13 @@ .ace_editor { border: 1px solid lightgray; margin: auto; - height: 200px; width: 80%; } .scrollmargin { height: 80px; - text-align: center; + } + .scrollmargin2 { + height: 180px; } @@ -26,16 +27,19 @@

 

+
+

+
diff --git a/demo/code_lens.html b/demo/code_lens.html new file mode 100644 index 00000000000..2e721f967cd --- /dev/null +++ b/demo/code_lens.html @@ -0,0 +1,124 @@ + + + + + ACE Code Lens demo + + + + +

+
+
+
+
+
+
+
diff --git a/demo/csp.html b/demo/csp.html
new file mode 100644
index 00000000000..a03f0fcae37
--- /dev/null
+++ b/demo/csp.html
@@ -0,0 +1,38 @@
+
+
+
+  
+  
+  
+  Editor
+
+
+

+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/diff/examples/editor.16.js b/demo/diff/examples/editor.16.js
new file mode 100644
index 00000000000..8fc5808b14d
--- /dev/null
+++ b/demo/diff/examples/editor.16.js
@@ -0,0 +1,2948 @@
+"use strict";
+
+var oop = require("./lib/oop");
+var dom = require("./lib/dom");
+var lang = require("./lib/lang");
+var useragent = require("./lib/useragent");
+var TextInput = require("./keyboard/textinput").TextInput;
+var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
+var FoldHandler = require("./mouse/fold_handler").FoldHandler;
+var KeyBinding = require("./keyboard/keybinding").KeyBinding;
+var EditSession = require("./edit_session").EditSession;
+var Search = require("./search").Search;
+var Range = require("./range").Range;
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+var CommandManager = require("./commands/command_manager").CommandManager;
+var defaultCommands = require("./commands/default_commands").commands;
+var config = require("./config");
+var TokenIterator = require("./token_iterator").TokenIterator;
+var LineWidgets = require("./line_widgets").LineWidgets;
+
+var clipboard = require("./clipboard");
+
+/**
+ * The main entry point into the Ace functionality.
+ *
+ * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.
+ *
+ * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.
+ * @class Editor
+ **/
+
+/**
+ * Creates a new `Editor` object.
+ *
+ * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything
+ * @param {EditSession} session The `EditSession` to refer to
+ *
+ *
+ * @constructor
+ **/
+var Editor = function(renderer, session, options) {
+    this.$toDestroy = [];
+    var container = renderer.getContainerElement();
+    this.container = container;
+    this.renderer = renderer;
+    this.id = "editor" + (++Editor.$uid);
+
+    this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
+    if (typeof document == "object") {
+        this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
+        this.renderer.textarea = this.textInput.getElement();
+        // TODO detect touch event support
+        this.$mouseHandler = new MouseHandler(this);
+        new FoldHandler(this);
+    }
+
+    this.keyBinding = new KeyBinding(this);
+
+    this.$search = new Search().set({
+        wrap: true
+    });
+
+    this.$historyTracker = this.$historyTracker.bind(this);
+    this.commands.on("exec", this.$historyTracker);
+
+    this.$initOperationListeners();
+    
+    this._$emitInputEvent = lang.delayedCall(function() {
+        this._signal("input", {});
+        if (this.session && !this.session.destroyed)
+            this.session.bgTokenizer.scheduleStart();
+    }.bind(this));
+    
+    this.on("change", function(_, _self) {
+        _self._$emitInputEvent.schedule(31);
+    });
+
+    this.setSession(session || options && options.session || new EditSession(""));
+    config.resetOptions(this);
+    if (options)
+        this.setOptions(options);
+    config._signal("editor", this);
+};
+
+Editor.$uid = 0;
+
+(function(){
+
+    oop.implement(this, EventEmitter);
+
+    this.$initOperationListeners = function() {
+        this.commands.on("exec", this.startOperation.bind(this), true);
+        this.commands.on("afterExec", this.endOperation.bind(this), true);
+
+        this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this, true));
+        
+        // todo: add before change events?
+        this.on("change", function() {
+            if (!this.curOp) {
+                this.startOperation();
+                this.curOp.selectionBefore = this.$lastSel;
+            }
+            this.curOp.docChanged = true;
+        }.bind(this), true);
+        
+        this.on("changeSelection", function() {
+            if (!this.curOp) {
+                this.startOperation();
+                this.curOp.selectionBefore = this.$lastSel;
+            }
+            this.curOp.selectionChanged = true;
+        }.bind(this), true);
+    };
+
+    this.curOp = null;
+    this.prevOp = {};
+    this.startOperation = function(commandEvent) {
+        if (this.curOp) {
+            if (!commandEvent || this.curOp.command)
+                return;
+            this.prevOp = this.curOp;
+        }
+        if (!commandEvent) {
+            this.previousCommand = null;
+            commandEvent = {};
+        }
+
+        this.$opResetTimer.schedule();
+        this.curOp = this.session.curOp = {
+            command: commandEvent.command || {},
+            args: commandEvent.args,
+            scrollTop: this.renderer.scrollTop
+        };
+        this.curOp.selectionBefore = this.selection.toJSON();
+    };
+
+    this.endOperation = function(e) {
+        if (this.curOp && this.session) {
+            if (e && e.returnValue === false || !this.session)
+                return (this.curOp = null);
+            if (e == true && this.curOp.command && this.curOp.command.name == "mouse")
+                return;
+            this._signal("beforeEndOperation");
+            if (!this.curOp) return;
+            var command = this.curOp.command;
+            var scrollIntoView = command && command.scrollIntoView;
+            if (scrollIntoView) {
+                switch (scrollIntoView) {
+                    case "center-animate":
+                        scrollIntoView = "animate";
+                        /* fall through */
+                    case "center":
+                        this.renderer.scrollCursorIntoView(null, 0.5);
+                        break;
+                    case "animate":
+                    case "cursor":
+                        this.renderer.scrollCursorIntoView();
+                        break;
+                    case "selectionPart":
+                        var range = this.selection.getRange();
+                        var config = this.renderer.layerConfig;
+                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {
+                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);
+                        }
+                        break;
+                    default:
+                        break;
+                }
+                if (scrollIntoView == "animate")
+                    this.renderer.animateScrolling(this.curOp.scrollTop);
+            }
+            var sel = this.selection.toJSON();
+            this.curOp.selectionAfter = sel;
+            this.$lastSel = this.selection.toJSON();
+            
+            // console.log(this.$lastSel+"  endOP")
+            this.session.getUndoManager().addSelection(sel);
+            this.prevOp = this.curOp;
+            this.curOp = null;
+        }
+    };
+
+    // TODO use property on commands instead of this
+    this.$mergeableCommands = ["backspace", "del", "insertstring"];
+    this.$historyTracker = function(e) {
+        if (!this.$mergeUndoDeltas)
+            return;
+
+        var prev = this.prevOp;
+        var mergeableCommands = this.$mergeableCommands;
+        // previous command was the same
+        var shouldMerge = prev.command && (e.command.name == prev.command.name);
+        if (e.command.name == "insertstring") {
+            var text = e.args;
+            if (this.mergeNextCommand === undefined)
+                this.mergeNextCommand = true;
+
+            shouldMerge = shouldMerge
+                && this.mergeNextCommand // previous command allows to coalesce with
+                && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type
+
+            this.mergeNextCommand = true;
+        } else {
+            shouldMerge = shouldMerge
+                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable
+        }
+
+        if (
+            this.$mergeUndoDeltas != "always"
+            && Date.now() - this.sequenceStartTime > 2000
+        ) {
+            shouldMerge = false; // the sequence is too long
+        }
+
+        if (shouldMerge)
+            this.session.mergeUndoDeltas = true;
+        else if (mergeableCommands.indexOf(e.command.name) !== -1)
+            this.sequenceStartTime = Date.now();
+    };
+
+    /**
+     * Sets a new key handler, such as "vim" or "windows".
+     * @param {String} keyboardHandler The new key handler
+     *
+     **/
+    this.setKeyboardHandler = function(keyboardHandler, cb) {
+        if (keyboardHandler && typeof keyboardHandler === "string" && keyboardHandler != "ace") {
+            this.$keybindingId = keyboardHandler;
+            var _self = this;
+            config.loadModule(["keybinding", keyboardHandler], function(module) {
+                if (_self.$keybindingId == keyboardHandler)
+                    _self.keyBinding.setKeyboardHandler(module && module.handler);
+                cb && cb();
+            });
+        } else {
+            this.$keybindingId = null;
+            this.keyBinding.setKeyboardHandler(keyboardHandler);
+            cb && cb();
+        }
+    };
+
+    /**
+     * Returns the keyboard handler, such as "vim" or "windows".
+     *
+     * @returns {String}
+     *
+     **/
+    this.getKeyboardHandler = function() {
+        return this.keyBinding.getKeyboardHandler();
+    };
+
+
+    /**
+     * Emitted whenever the [[EditSession]] changes.
+     * @event changeSession
+     * @param {Object} e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s.
+     *
+     **/
+    /**
+     * Sets a new editsession to use. This method also emits the `'changeSession'` event.
+     * @param {EditSession} session The new session to use
+     *
+     **/
+    this.setSession = function(session) {
+        if (this.session == session)
+            return;
+        
+        // make sure operationEnd events are not emitted to wrong session
+        if (this.curOp) this.endOperation();
+        this.curOp = {};
+
+        var oldSession = this.session;
+        if (oldSession) {
+            this.session.off("change", this.$onDocumentChange);
+            this.session.off("changeMode", this.$onChangeMode);
+            this.session.off("tokenizerUpdate", this.$onTokenizerUpdate);
+            this.session.off("changeTabSize", this.$onChangeTabSize);
+            this.session.off("changeWrapLimit", this.$onChangeWrapLimit);
+            this.session.off("changeWrapMode", this.$onChangeWrapMode);
+            this.session.off("changeFold", this.$onChangeFold);
+            this.session.off("changeFrontMarker", this.$onChangeFrontMarker);
+            this.session.off("changeBackMarker", this.$onChangeBackMarker);
+            this.session.off("changeBreakpoint", this.$onChangeBreakpoint);
+            this.session.off("changeAnnotation", this.$onChangeAnnotation);
+            this.session.off("changeOverwrite", this.$onCursorChange);
+            this.session.off("changeScrollTop", this.$onScrollTopChange);
+            this.session.off("changeScrollLeft", this.$onScrollLeftChange);
+
+            var selection = this.session.getSelection();
+            selection.off("changeCursor", this.$onCursorChange);
+            selection.off("changeSelection", this.$onSelectionChange);
+        }
+
+        this.session = session;
+        if (session) {
+            this.$onDocumentChange = this.onDocumentChange.bind(this);
+            session.on("change", this.$onDocumentChange);
+            this.renderer.setSession(session);
+    
+            this.$onChangeMode = this.onChangeMode.bind(this);
+            session.on("changeMode", this.$onChangeMode);
+    
+            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
+            session.on("tokenizerUpdate", this.$onTokenizerUpdate);
+    
+            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
+            session.on("changeTabSize", this.$onChangeTabSize);
+    
+            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
+            session.on("changeWrapLimit", this.$onChangeWrapLimit);
+    
+            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
+            session.on("changeWrapMode", this.$onChangeWrapMode);
+    
+            this.$onChangeFold = this.onChangeFold.bind(this);
+            session.on("changeFold", this.$onChangeFold);
+    
+            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
+            this.session.on("changeFrontMarker", this.$onChangeFrontMarker);
+    
+            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
+            this.session.on("changeBackMarker", this.$onChangeBackMarker);
+    
+            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
+            this.session.on("changeBreakpoint", this.$onChangeBreakpoint);
+    
+            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
+            this.session.on("changeAnnotation", this.$onChangeAnnotation);
+    
+            this.$onCursorChange = this.onCursorChange.bind(this);
+            this.session.on("changeOverwrite", this.$onCursorChange);
+    
+            this.$onScrollTopChange = this.onScrollTopChange.bind(this);
+            this.session.on("changeScrollTop", this.$onScrollTopChange);
+    
+            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
+            this.session.on("changeScrollLeft", this.$onScrollLeftChange);
+    
+            this.selection = session.getSelection();
+            this.selection.on("changeCursor", this.$onCursorChange);
+    
+            this.$onSelectionChange = this.onSelectionChange.bind(this);
+            this.selection.on("changeSelection", this.$onSelectionChange);
+    
+            this.onChangeMode();
+    
+            this.onCursorChange();
+    
+            this.onScrollTopChange();
+            this.onScrollLeftChange();
+            this.onSelectionChange();
+            this.onChangeFrontMarker();
+            this.onChangeBackMarker();
+            this.onChangeBreakpoint();
+            this.onChangeAnnotation();
+            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
+            this.renderer.updateFull();
+        } else {
+            this.selection = null;
+            this.renderer.setSession(session);
+        }
+
+        this._signal("changeSession", {
+            session: session,
+            oldSession: oldSession
+        });
+        
+        this.curOp = null;
+        
+        oldSession && oldSession._signal("changeEditor", {oldEditor: this});
+        session && session._signal("changeEditor", {editor: this});
+        
+        if (session && !session.destroyed)
+            session.bgTokenizer.scheduleStart();
+    };
+
+    /**
+     * Returns the current session being used.
+     * @returns {EditSession}
+     **/
+    this.getSession = function() {
+        return this.session;
+    };
+
+    /**
+     * Sets the current document to `val`.
+     * @param {String} val The new value to set for the document
+     * @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
+     *
+     * @returns {String} The current document value
+     * @related Document.setValue
+     **/
+    this.setValue = function(val, cursorPos) {
+        this.session.doc.setValue(val);
+
+        if (!cursorPos)
+            this.selectAll();
+        else if (cursorPos == 1)
+            this.navigateFileEnd();
+        else if (cursorPos == -1)
+            this.navigateFileStart();
+
+        return val;
+    };
+
+    /**
+     * Returns the current session's content.
+     *
+     * @returns {String}
+     * @related EditSession.getValue
+     **/
+    this.getValue = function() {
+        return this.session.getValue();
+    };
+
+    /**
+     *
+     * Returns the currently highlighted selection.
+     * @returns {Selection} The selection object
+     **/
+    this.getSelection = function() {
+        return this.selection;
+    };
+
+    /**
+     * {:VirtualRenderer.onResize}
+     * @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed
+     *
+     *
+     * @related VirtualRenderer.onResize
+     **/
+    this.resize = function(force) {
+        this.renderer.onResize(force);
+    };
+
+    /**
+     * {:VirtualRenderer.setTheme}
+     * @param {String} theme The path to a theme
+     * @param {Function} cb optional callback called when theme is loaded
+     **/
+    this.setTheme = function(theme, cb) {
+        this.renderer.setTheme(theme, cb);
+    };
+
+    /**
+     * {:VirtualRenderer.getTheme}
+     *
+     * @returns {String} The set theme
+     * @related VirtualRenderer.getTheme
+     **/
+    this.getTheme = function() {
+        return this.renderer.getTheme();
+    };
+
+    /**
+     * {:VirtualRenderer.setStyle}
+     * @param {String} style A class name
+     *
+     *
+     * @related VirtualRenderer.setStyle
+     **/
+    this.setStyle = function(style) {
+        this.renderer.setStyle(style);
+    };
+
+    /**
+     * {:VirtualRenderer.unsetStyle}
+     * @related VirtualRenderer.unsetStyle
+     **/
+    this.unsetStyle = function(style) {
+        this.renderer.unsetStyle(style);
+    };
+
+    /**
+     * Gets the current font size of the editor text.
+     */
+    this.getFontSize = function () {
+        return this.getOption("fontSize") ||
+           dom.computedStyle(this.container).fontSize;
+    };
+
+    /**
+     * Set a new font size (in pixels) for the editor text.
+     * @param {String} size A font size ( _e.g._ "12px")
+     *
+     *
+     **/
+    this.setFontSize = function(size) {
+        this.setOption("fontSize", size);
+    };
+
+    this.$highlightBrackets = function() {
+        if (this.$highlightPending) {
+            return;
+        }
+
+        // perform highlight async to not block the browser during navigation
+        var self = this;
+        this.$highlightPending = true;
+        setTimeout(function () {
+            self.$highlightPending = false;
+            var session = self.session;
+            if (!session || session.destroyed) return;
+            if (session.$bracketHighlight) {
+                session.$bracketHighlight.markerIds.forEach(function(id) {
+                    session.removeMarker(id);
+                });
+                session.$bracketHighlight = null;
+            }
+            var pos = self.getCursorPosition();
+            var handler = self.getKeyboardHandler();
+            var isBackwards = handler && handler.$getDirectionForHighlight && handler.$getDirectionForHighlight(self);
+            var ranges = session.getMatchingBracketRanges(pos, isBackwards);
+
+            if (!ranges) {
+                var iterator = new TokenIterator(session, pos.row, pos.column);
+                var token = iterator.getCurrentToken();
+
+                if (token && /\b(?:tag-open|tag-name)/.test(token.type)) {
+                    var tagNamesRanges = session.getMatchingTags(pos);
+                    if (tagNamesRanges) ranges = [tagNamesRanges.openTagName, tagNamesRanges.closeTagName];
+                }
+            }
+            if (!ranges && session.$mode.getMatching)
+                ranges = session.$mode.getMatching(self.session);
+            if (!ranges) {
+                if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();
+                return;
+            }
+
+            var markerType = "ace_bracket";
+            if (!Array.isArray(ranges)) {
+                ranges = [ranges];
+            } else if (ranges.length == 1) {
+                markerType = "ace_error_bracket";
+            }
+
+            // show adjacent ranges as one
+            if (ranges.length == 2) {
+                if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)
+                    ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];
+                else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)
+                    ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];
+            }
+
+            session.$bracketHighlight = {
+                ranges: ranges,
+                markerIds: ranges.map(function(range) {
+                    return session.addMarker(range, markerType, "text");
+                })
+            };
+            if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();
+        }, 50);
+    };
+
+    /**
+     *
+     * Brings the current `textInput` into focus.
+     **/
+    this.focus = function() {
+        this.textInput.focus();
+    };
+
+    /**
+     * Returns `true` if the current `textInput` is in focus.
+     * @return {Boolean}
+     **/
+    this.isFocused = function() {
+        return this.textInput.isFocused();
+    };
+
+    /**
+     *
+     * Blurs the current `textInput`.
+     **/
+    this.blur = function() {
+        this.textInput.blur();
+    };
+
+    /**
+     * Emitted once the editor comes into focus.
+     * @event focus
+     *
+     *
+     **/
+    this.onFocus = function(e) {
+        if (this.$isFocused)
+            return;
+        this.$isFocused = true;
+        this.renderer.showCursor();
+        this.renderer.visualizeFocus();
+        this._emit("focus", e);
+    };
+
+    /**
+     * Emitted once the editor has been blurred.
+     * @event blur
+     *
+     *
+     **/
+    this.onBlur = function(e) {
+        if (!this.$isFocused)
+            return;
+        this.$isFocused = false;
+        this.renderer.hideCursor();
+        this.renderer.visualizeBlur();
+        this._emit("blur", e);
+    };
+
+    this.$cursorChange = function() {
+        this.renderer.updateCursor();
+        this.$highlightBrackets();
+        this.$updateHighlightActiveLine();
+    };
+
+    /**
+     * Emitted whenever the document is changed.
+     * @event change
+     * @param {Object} e Contains a single property, `data`, which has the delta of changes
+     *
+     *
+     *
+     **/
+    this.onDocumentChange = function(delta) {
+        // Rerender and emit "change" event.
+        var wrap = this.session.$useWrapMode;
+        var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);
+        this.renderer.updateLines(delta.start.row, lastRow, wrap);
+
+        this._signal("change", delta);
+        
+        // Update cursor because tab characters can influence the cursor position.
+        this.$cursorChange();
+    };
+
+    this.onTokenizerUpdate = function(e) {
+        var rows = e.data;
+        this.renderer.updateLines(rows.first, rows.last);
+    };
+
+
+    this.onScrollTopChange = function() {
+        this.renderer.scrollToY(this.session.getScrollTop());
+    };
+
+    this.onScrollLeftChange = function() {
+        this.renderer.scrollToX(this.session.getScrollLeft());
+    };
+
+    /**
+     * Emitted when the selection changes.
+     *
+     **/
+    this.onCursorChange = function() {
+        this.$cursorChange();
+        this._signal("changeSelection");
+    };
+
+    this.$updateHighlightActiveLine = function() {
+        var session = this.getSession();
+
+        var highlight;
+        if (this.$highlightActiveLine) {
+            if (this.$selectionStyle != "line" || !this.selection.isMultiLine())
+                highlight = this.getCursorPosition();
+            if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty())
+                highlight = false;
+            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))
+                highlight = false;
+        }
+
+        if (session.$highlightLineMarker && !highlight) {
+            session.removeMarker(session.$highlightLineMarker.id);
+            session.$highlightLineMarker = null;
+        } else if (!session.$highlightLineMarker && highlight) {
+            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
+            range.id = session.addMarker(range, "ace_active-line", "screenLine");
+            session.$highlightLineMarker = range;
+        } else if (highlight) {
+            session.$highlightLineMarker.start.row = highlight.row;
+            session.$highlightLineMarker.end.row = highlight.row;
+            session.$highlightLineMarker.start.column = highlight.column;
+            session._signal("changeBackMarker");
+        }
+    };
+
+    this.onSelectionChange = function(e) {
+        var session = this.session;
+
+        if (session.$selectionMarker) {
+            session.removeMarker(session.$selectionMarker);
+        }
+        session.$selectionMarker = null;
+
+        if (!this.selection.isEmpty()) {
+            var range = this.selection.getRange();
+            var style = this.getSelectionStyle();
+            session.$selectionMarker = session.addMarker(range, "ace_selection", style);
+        } else {
+            this.$updateHighlightActiveLine();
+        }
+
+        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();
+        this.session.highlight(re);
+
+        this._signal("changeSelection");
+    };
+
+    this.$getSelectionHighLightRegexp = function() {
+        var session = this.session;
+
+        var selection = this.getSelectionRange();
+        if (selection.isEmpty() || selection.isMultiLine())
+            return;
+
+        var startColumn = selection.start.column;
+        var endColumn = selection.end.column;
+        var line = session.getLine(selection.start.row);
+        
+        var needle = line.substring(startColumn, endColumn);
+        // maximum allowed size for regular expressions in 32000, 
+        // but getting close to it has significant impact on the performance
+        if (needle.length > 5000 || !/[\w\d]/.test(needle))
+            return;
+
+        var re = this.$search.$assembleRegExp({
+            wholeWord: true,
+            caseSensitive: true,
+            needle: needle
+        });
+        
+        var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1);
+        if (!re.test(wordWithBoundary))
+            return;
+        
+        return re;
+    };
+
+
+    this.onChangeFrontMarker = function() {
+        this.renderer.updateFrontMarkers();
+    };
+
+    this.onChangeBackMarker = function() {
+        this.renderer.updateBackMarkers();
+    };
+
+
+    this.onChangeBreakpoint = function() {
+        this.renderer.updateBreakpoints();
+    };
+
+    this.onChangeAnnotation = function() {
+        this.renderer.setAnnotations(this.session.getAnnotations());
+    };
+
+
+    this.onChangeMode = function(e) {
+        this.renderer.updateText();
+        this._emit("changeMode", e);
+    };
+
+
+    this.onChangeWrapLimit = function() {
+        this.renderer.updateFull();
+    };
+
+    this.onChangeWrapMode = function() {
+        this.renderer.onResize(true);
+    };
+
+
+    this.onChangeFold = function() {
+        // Update the active line marker as due to folding changes the current
+        // line range on the screen might have changed.
+        this.$updateHighlightActiveLine();
+        // TODO: This might be too much updating. Okay for now.
+        this.renderer.updateFull();
+    };
+
+    
+    /**
+     * Returns the string of text currently highlighted.
+     * @returns {String}
+     **/
+    this.getSelectedText = function() {
+        return this.session.getTextRange(this.getSelectionRange());
+    };
+    
+    /**
+     * Emitted when text is copied.
+     * @event copy
+     * @param {String} text The copied text
+     *
+     **/
+    /**
+     * Returns the string of text currently highlighted.
+     * @returns {String}
+     **/
+    this.getCopyText = function() {
+        var text = this.getSelectedText();
+        var nl = this.session.doc.getNewLineCharacter();
+        var copyLine= false;
+        if (!text && this.$copyWithEmptySelection) {
+            copyLine = true;
+            var ranges = this.selection.getAllRanges();
+            for (var i = 0; i < ranges.length; i++) {
+                var range = ranges[i];
+                if (i && ranges[i - 1].start.row == range.start.row)
+                    continue;
+                text += this.session.getLine(range.start.row) + nl;
+            }
+        }
+        var e = {text: text};
+        this._signal("copy", e);
+        clipboard.lineMode = copyLine ? e.text : false;
+        return e.text;
+    };
+
+    /**
+     * Called whenever a text "copy" happens.
+     **/
+    this.onCopy = function() {
+        this.commands.exec("copy", this);
+    };
+
+    /**
+     * Called whenever a text "cut" happens.
+     **/
+    this.onCut = function() {
+        this.commands.exec("cut", this);
+    };
+
+    /**
+     * Emitted when text is pasted.
+     * @event paste
+     * @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.
+     *
+     *
+     **/
+    /**
+     * Called whenever a text "paste" happens.
+     * @param {String} text The pasted text
+     *
+     *
+     **/
+    this.onPaste = function(text, event) {
+        var e = {text: text, event: event};
+        this.commands.exec("paste", this, e);
+    };
+    
+    this.$handlePaste = function(e) {
+        if (typeof e == "string") 
+            e = {text: e};
+        this._signal("paste", e);
+        var text = e.text;
+
+        var lineMode = text === clipboard.lineMode;
+        var session = this.session;
+        if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {
+            if (lineMode)
+                session.insert({ row: this.selection.lead.row, column: 0 }, text);
+            else
+                this.insert(text);
+        } else if (lineMode) {
+            this.selection.rangeList.ranges.forEach(function(range) {
+                session.insert({ row: range.start.row, column: 0 }, text);
+            });
+        } else {
+            var lines = text.split(/\r\n|\r|\n/);
+            var ranges = this.selection.rangeList.ranges;
+    
+            var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]);
+            if (lines.length != ranges.length || isFullLine)
+                return this.commands.exec("insertstring", this, text);
+    
+            for (var i = ranges.length; i--;) {
+                var range = ranges[i];
+                if (!range.isEmpty())
+                    session.remove(range);
+    
+                session.insert(range.start, lines[i]);
+            }
+        }
+    };
+
+    this.execCommand = function(command, args) {
+        return this.commands.exec(command, this, args);
+    };
+
+    /**
+     * Inserts `text` into wherever the cursor is pointing.
+     * @param {String} text The new text to add
+     *
+     **/
+    this.insert = function(text, pasted) {
+        var session = this.session;
+        var mode = session.getMode();
+        var cursor = this.getCursorPosition();
+
+        if (this.getBehavioursEnabled() && !pasted) {
+            // Get a transform if the current mode wants one.
+            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
+            if (transform) {
+                if (text !== transform.text) {
+                    // keep automatic insertion in a separate delta, unless it is in multiselect mode
+                    if (!this.inVirtualSelectionMode) {
+                        this.session.mergeUndoDeltas = false;
+                        this.mergeNextCommand = false;
+                    }
+                }
+                text = transform.text;
+
+            }
+        }
+        
+        if (text == "\t")
+            text = this.session.getTabString();
+
+        // remove selected text
+        if (!this.selection.isEmpty()) {
+            var range = this.getSelectionRange();
+            cursor = this.session.remove(range);
+            this.clearSelection();
+        }
+        else if (this.session.getOverwrite() && text.indexOf("\n") == -1) {
+            var range = new Range.fromPoints(cursor, cursor);
+            range.end.column += text.length;
+            this.session.remove(range);
+        }
+
+        if (text == "\n" || text == "\r\n") {
+            var line = session.getLine(cursor.row);
+            if (cursor.column > line.search(/\S|$/)) {
+                var d = line.substr(cursor.column).search(/\S|$/);
+                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);
+            }
+        }
+        this.clearSelection();
+
+        var start = cursor.column;
+        var lineState = session.getState(cursor.row);
+        var line = session.getLine(cursor.row);
+        var shouldOutdent = mode.checkOutdent(lineState, line, text);
+        session.insert(cursor, text);
+
+        if (transform && transform.selection) {
+            if (transform.selection.length == 2) { // Transform relative to the current column
+                this.selection.setSelectionRange(
+                    new Range(cursor.row, start + transform.selection[0],
+                              cursor.row, start + transform.selection[1]));
+            } else { // Transform relative to the current row.
+                this.selection.setSelectionRange(
+                    new Range(cursor.row + transform.selection[0],
+                              transform.selection[1],
+                              cursor.row + transform.selection[2],
+                              transform.selection[3]));
+            }
+        }
+        if (this.$enableAutoIndent) {
+            if (session.getDocument().isNewLine(text)) {
+                var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
+
+                session.insert({row: cursor.row+1, column: 0}, lineIndent);
+            }
+            if (shouldOutdent)
+                mode.autoOutdent(lineState, session, cursor.row);
+        }
+    };
+
+    this.autoIndent = function () {
+        var session = this.session;
+        var mode = session.getMode();
+
+        var startRow, endRow;
+        if (this.selection.isEmpty()) {
+            startRow = 0;
+            endRow = session.doc.getLength() - 1;
+        } else {
+            var selectedRange = this.getSelectionRange();
+
+            startRow = selectedRange.start.row;
+            endRow = selectedRange.end.row;
+        }
+
+        var prevLineState = "";
+        var prevLine = "";
+        var lineIndent = "";
+        var line, currIndent, range;
+        var tab = session.getTabString();
+
+        for (var row = startRow; row <= endRow; row++) {
+            if (row > 0) {
+                prevLineState = session.getState(row - 1);
+                prevLine = session.getLine(row - 1);
+                lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab);
+            }
+
+            line = session.getLine(row);
+            currIndent = mode.$getIndent(line);
+            if (lineIndent !== currIndent) {
+                if (currIndent.length > 0) {
+                    range = new Range(row, 0, row, currIndent.length);
+                    session.remove(range);
+                }
+                if (lineIndent.length > 0) {
+                    session.insert({row: row, column: 0}, lineIndent);
+                }
+            }
+
+            mode.autoOutdent(prevLineState, session, row);
+        }
+    };
+
+
+    this.onTextInput = function(text, composition) {
+        if (!composition)
+            return this.keyBinding.onTextInput(text);
+        
+        this.startOperation({command: { name: "insertstring" }});
+        var applyComposition = this.applyComposition.bind(this, text, composition);
+        if (this.selection.rangeCount)
+            this.forEachSelection(applyComposition);
+        else
+            applyComposition();
+        this.endOperation();
+    };
+    
+    this.applyComposition = function(text, composition) {
+        if (composition.extendLeft || composition.extendRight) {
+            var r = this.selection.getRange();
+            r.start.column -= composition.extendLeft;
+            r.end.column += composition.extendRight;
+            if (r.start.column < 0) {
+                r.start.row--;
+                r.start.column += this.session.getLine(r.start.row).length + 1;
+            }
+            this.selection.setRange(r);
+            if (!text && !r.isEmpty())
+                this.remove();
+        }
+        if (text || !this.selection.isEmpty())
+            this.insert(text, true);
+        if (composition.restoreStart || composition.restoreEnd) {
+            var r = this.selection.getRange();
+            r.start.column -= composition.restoreStart;
+            r.end.column -= composition.restoreEnd;
+            this.selection.setRange(r);
+        }
+    };
+
+    this.onCommandKey = function(e, hashId, keyCode) {
+        return this.keyBinding.onCommandKey(e, hashId, keyCode);
+    };
+
+    /**
+     * 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.
+     * @param {Boolean} overwrite Defines whether or not to set overwrites
+     *
+     *
+     * @related EditSession.setOverwrite
+     **/
+    this.setOverwrite = function(overwrite) {
+        this.session.setOverwrite(overwrite);
+    };
+
+    /**
+     * Returns `true` if overwrites are enabled; `false` otherwise.
+     * @returns {Boolean}
+     * @related EditSession.getOverwrite
+     **/
+    this.getOverwrite = function() {
+        return this.session.getOverwrite();
+    };
+
+    /**
+     * Sets the value of overwrite to the opposite of whatever it currently is.
+     * @related EditSession.toggleOverwrite
+     **/
+    this.toggleOverwrite = function() {
+        this.session.toggleOverwrite();
+    };
+
+    /**
+     * Sets how fast the mouse scrolling should do.
+     * @param {Number} speed A value indicating the new speed (in milliseconds)
+     **/
+    this.setScrollSpeed = function(speed) {
+        this.setOption("scrollSpeed", speed);
+    };
+
+    /**
+     * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).
+     * @returns {Number}
+     **/
+    this.getScrollSpeed = function() {
+        return this.getOption("scrollSpeed");
+    };
+
+    /**
+     * Sets the delay (in milliseconds) of the mouse drag.
+     * @param {Number} dragDelay A value indicating the new delay
+     **/
+    this.setDragDelay = function(dragDelay) {
+        this.setOption("dragDelay", dragDelay);
+    };
+
+    /**
+     * Returns the current mouse drag delay.
+     * @returns {Number}
+     **/
+    this.getDragDelay = function() {
+        return this.getOption("dragDelay");
+    };
+
+    /**
+     * Emitted when the selection style changes, via [[Editor.setSelectionStyle]].
+     * @event changeSelectionStyle
+     * @param {Object} data Contains one property, `data`, which indicates the new selection style
+     **/
+    /**
+     * Draw selection markers spanning whole line, or only over selected text. Default value is "line"
+     * @param {String} style The new selection style "line"|"text"
+     *
+     **/
+    this.setSelectionStyle = function(val) {
+        this.setOption("selectionStyle", val);
+    };
+
+    /**
+     * Returns the current selection style.
+     * @returns {String}
+     **/
+    this.getSelectionStyle = function() {
+        return this.getOption("selectionStyle");
+    };
+
+    /**
+     * Determines whether or not the current line should be highlighted.
+     * @param {Boolean} shouldHighlight Set to `true` to highlight the current line
+     **/
+    this.setHighlightActiveLine = function(shouldHighlight) {
+        this.setOption("highlightActiveLine", shouldHighlight);
+    };
+    /**
+     * Returns `true` if current lines are always highlighted.
+     * @return {Boolean}
+     **/
+    this.getHighlightActiveLine = function() {
+        return this.getOption("highlightActiveLine");
+    };
+    this.setHighlightGutterLine = function(shouldHighlight) {
+        this.setOption("highlightGutterLine", shouldHighlight);
+    };
+
+    this.getHighlightGutterLine = function() {
+        return this.getOption("highlightGutterLine");
+    };
+
+    /**
+     * Determines if the currently selected word should be highlighted.
+     * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word
+     *
+     **/
+    this.setHighlightSelectedWord = function(shouldHighlight) {
+        this.setOption("highlightSelectedWord", shouldHighlight);
+    };
+
+    /**
+     * Returns `true` if currently highlighted words are to be highlighted.
+     * @returns {Boolean}
+     **/
+    this.getHighlightSelectedWord = function() {
+        return this.$highlightSelectedWord;
+    };
+
+    this.setAnimatedScroll = function(shouldAnimate){
+        this.renderer.setAnimatedScroll(shouldAnimate);
+    };
+
+    this.getAnimatedScroll = function(){
+        return this.renderer.getAnimatedScroll();
+    };
+
+    /**
+     * If `showInvisibles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor.
+     * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters
+     *
+     **/
+    this.setShowInvisibles = function(showInvisibles) {
+        this.renderer.setShowInvisibles(showInvisibles);
+    };
+
+    /**
+     * Returns `true` if invisible characters are being shown.
+     * @returns {Boolean}
+     **/
+    this.getShowInvisibles = function() {
+        return this.renderer.getShowInvisibles();
+    };
+
+    this.setDisplayIndentGuides = function(display) {
+        this.renderer.setDisplayIndentGuides(display);
+    };
+
+    this.getDisplayIndentGuides = function() {
+        return this.renderer.getDisplayIndentGuides();
+    };
+
+    this.setHighlightIndentGuides = function(highlight) {
+        this.renderer.setHighlightIndentGuides(highlight);
+    };
+
+    this.getHighlightIndentGuides = function() {
+        return this.renderer.getHighlightIndentGuides();
+    };
+
+    /**
+     * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.
+     * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin
+     *
+     **/
+    this.setShowPrintMargin = function(showPrintMargin) {
+        this.renderer.setShowPrintMargin(showPrintMargin);
+    };
+
+    /**
+     * Returns `true` if the print margin is being shown.
+     * @returns {Boolean}
+     **/
+    this.getShowPrintMargin = function() {
+        return this.renderer.getShowPrintMargin();
+    };
+
+    /**
+     * Sets the column defining where the print margin should be.
+     * @param {Number} showPrintMargin Specifies the new print margin
+     *
+     **/
+    this.setPrintMarginColumn = function(showPrintMargin) {
+        this.renderer.setPrintMarginColumn(showPrintMargin);
+    };
+
+    /**
+     * Returns the column number of where the print margin is.
+     * @returns {Number}
+     **/
+    this.getPrintMarginColumn = function() {
+        return this.renderer.getPrintMarginColumn();
+    };
+
+    /**
+     * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.
+     * @param {Boolean} readOnly Specifies whether the editor can be modified or not
+     *
+     **/
+    this.setReadOnly = function(readOnly) {
+        this.setOption("readOnly", readOnly);
+    };
+
+    /**
+     * Returns `true` if the editor is set to read-only mode.
+     * @returns {Boolean}
+     **/
+    this.getReadOnly = function() {
+        return this.getOption("readOnly");
+    };
+
+    /**
+     * 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}
+     * @param {Boolean} enabled Enables or disables behaviors
+     *
+     **/
+    this.setBehavioursEnabled = function (enabled) {
+        this.setOption("behavioursEnabled", enabled);
+    };
+
+    /**
+     * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}
+     *
+     * @returns {Boolean}
+     **/
+    this.getBehavioursEnabled = function () {
+        return this.getOption("behavioursEnabled");
+    };
+
+    /**
+     * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets
+     * when such a character is typed in.
+     * @param {Boolean} enabled Enables or disables wrapping behaviors
+     *
+     **/
+    this.setWrapBehavioursEnabled = function (enabled) {
+        this.setOption("wrapBehavioursEnabled", enabled);
+    };
+
+    /**
+     * Returns `true` if the wrapping behaviors are currently enabled.
+     **/
+    this.getWrapBehavioursEnabled = function () {
+        return this.getOption("wrapBehavioursEnabled");
+    };
+
+    /**
+     * Indicates whether the fold widgets should be shown or not.
+     * @param {Boolean} show Specifies whether the fold widgets are shown
+     **/
+    this.setShowFoldWidgets = function(show) {
+        this.setOption("showFoldWidgets", show);
+
+    };
+    /**
+     * Returns `true` if the fold widgets are shown.
+     * @return {Boolean}
+     **/
+    this.getShowFoldWidgets = function() {
+        return this.getOption("showFoldWidgets");
+    };
+
+    this.setFadeFoldWidgets = function(fade) {
+        this.setOption("fadeFoldWidgets", fade);
+    };
+
+    this.getFadeFoldWidgets = function() {
+        return this.getOption("fadeFoldWidgets");
+    };
+
+    /**
+     * Removes the current selection or one character.
+     * @param {String} dir The direction of the deletion to occur, either "left" or "right"
+     *
+     **/
+    this.remove = function(dir) {
+        if (this.selection.isEmpty()){
+            if (dir == "left")
+                this.selection.selectLeft();
+            else
+                this.selection.selectRight();
+        }
+
+        var range = this.getSelectionRange();
+        if (this.getBehavioursEnabled()) {
+            var session = this.session;
+            var state = session.getState(range.start.row);
+            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
+
+            if (range.end.column === 0) {
+                var text = session.getTextRange(range);
+                if (text[text.length - 1] == "\n") {
+                    var line = session.getLine(range.end.row);
+                    if (/^\s+$/.test(line)) {
+                        range.end.column = line.length;
+                    }
+                }
+            }
+            if (new_range)
+                range = new_range;
+        }
+
+        this.session.remove(range);
+        this.clearSelection();
+    };
+
+    /**
+     * Removes the word directly to the right of the current selection.
+     **/
+    this.removeWordRight = function() {
+        if (this.selection.isEmpty())
+            this.selection.selectWordRight();
+
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    };
+
+    /**
+     * Removes the word directly to the left of the current selection.
+     **/
+    this.removeWordLeft = function() {
+        if (this.selection.isEmpty())
+            this.selection.selectWordLeft();
+
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    };
+
+    /**
+     * Removes all the words to the left of the current selection, until the start of the line.
+     **/
+    this.removeToLineStart = function() {
+        if (this.selection.isEmpty())
+            this.selection.selectLineStart();
+        if (this.selection.isEmpty())
+            this.selection.selectLeft();
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    };
+
+    /**
+     * Removes all the words to the right of the current selection, until the end of the line.
+     **/
+    this.removeToLineEnd = function() {
+        if (this.selection.isEmpty())
+            this.selection.selectLineEnd();
+
+        var range = this.getSelectionRange();
+        if (range.start.column == range.end.column && range.start.row == range.end.row) {
+            range.end.column = 0;
+            range.end.row++;
+        }
+
+        this.session.remove(range);
+        this.clearSelection();
+    };
+
+    /**
+     * Splits the line at the current selection (by inserting an `'\n'`).
+     **/
+    this.splitLine = function() {
+        if (!this.selection.isEmpty()) {
+            this.session.remove(this.getSelectionRange());
+            this.clearSelection();
+        }
+
+        var cursor = this.getCursorPosition();
+        this.insert("\n");
+        this.moveCursorToPosition(cursor);
+    };
+
+    /**
+     * Set the "ghost" text in provided position. "Ghost" text is a kind of
+     * preview text inside the editor which can be used to preview some code
+     * inline in the editor such as, for example, code completions.
+     * 
+     * @param {String} text Text to be inserted as "ghost" text
+     * @param {object} position Position to insert text to
+     */
+    this.setGhostText = function(text, position) {
+        if (!this.session.widgetManager) {
+            this.session.widgetManager = new LineWidgets(this.session);
+            this.session.widgetManager.attach(this);
+        }
+        this.renderer.setGhostText(text, position);
+    };
+
+    /**
+     * Removes "ghost" text currently displayed in the editor.
+     */
+    this.removeGhostText = function() {
+        if (!this.session.widgetManager) return;
+
+        this.renderer.removeGhostText();
+    };
+
+    /**
+     * Transposes current line.
+     **/
+    this.transposeLetters = function() {
+        if (!this.selection.isEmpty()) {
+            return;
+        }
+
+        var cursor = this.getCursorPosition();
+        var column = cursor.column;
+        if (column === 0)
+            return;
+
+        var line = this.session.getLine(cursor.row);
+        var swap, range;
+        if (column < line.length) {
+            swap = line.charAt(column) + line.charAt(column-1);
+            range = new Range(cursor.row, column-1, cursor.row, column+1);
+        }
+        else {
+            swap = line.charAt(column-1) + line.charAt(column-2);
+            range = new Range(cursor.row, column-2, cursor.row, column);
+        }
+        this.session.replace(range, swap);
+        this.session.selection.moveToPosition(range.end);
+    };
+
+    /**
+     * Converts the current selection entirely into lowercase.
+     **/
+    this.toLowerCase = function() {
+        var originalRange = this.getSelectionRange();
+        if (this.selection.isEmpty()) {
+            this.selection.selectWord();
+        }
+
+        var range = this.getSelectionRange();
+        var text = this.session.getTextRange(range);
+        this.session.replace(range, text.toLowerCase());
+        this.selection.setSelectionRange(originalRange);
+    };
+
+    /**
+     * Converts the current selection entirely into uppercase.
+     **/
+    this.toUpperCase = function() {
+        var originalRange = this.getSelectionRange();
+        if (this.selection.isEmpty()) {
+            this.selection.selectWord();
+        }
+
+        var range = this.getSelectionRange();
+        var text = this.session.getTextRange(range);
+        this.session.replace(range, text.toUpperCase());
+        this.selection.setSelectionRange(originalRange);
+    };
+
+    /**
+     * Inserts an indentation into the current cursor position or indents the selected lines.
+     *
+     * @related EditSession.indentRows
+     **/
+    this.indent = function() {
+        var session = this.session;
+        var range = this.getSelectionRange();
+
+        if (range.start.row < range.end.row) {
+            var rows = this.$getSelectedRows();
+            session.indentRows(rows.first, rows.last, "\t");
+            return;
+        } else if (range.start.column < range.end.column) {
+            var text = session.getTextRange(range);
+            if (!/^\s+$/.test(text)) {
+                var rows = this.$getSelectedRows();
+                session.indentRows(rows.first, rows.last, "\t");
+                return;
+            }
+        }
+        
+        var line = session.getLine(range.start.row);
+        var position = range.start;
+        var size = session.getTabSize();
+        var column = session.documentToScreenColumn(position.row, position.column);
+
+        if (this.session.getUseSoftTabs()) {
+            var count = (size - column % size);
+            var indentString = lang.stringRepeat(" ", count);
+        } else {
+            var count = column % size;
+            while (line[range.start.column - 1] == " " && count) {
+                range.start.column--;
+                count--;
+            }
+            this.selection.setSelectionRange(range);
+            indentString = "\t";
+        }
+        return this.insert(indentString);
+    };
+
+    /**
+     * Indents the current line.
+     * @related EditSession.indentRows
+     **/
+    this.blockIndent = function() {
+        var rows = this.$getSelectedRows();
+        this.session.indentRows(rows.first, rows.last, "\t");
+    };
+
+    /**
+     * Outdents the current line.
+     * @related EditSession.outdentRows
+     **/
+    this.blockOutdent = function() {
+        var selection = this.session.getSelection();
+        this.session.outdentRows(selection.getRange());
+    };
+
+    // TODO: move out of core when we have good mechanism for managing extensions
+    this.sortLines = function() {
+        var rows = this.$getSelectedRows();
+        var session = this.session;
+
+        var lines = [];
+        for (var i = rows.first; i <= rows.last; i++)
+            lines.push(session.getLine(i));
+
+        lines.sort(function(a, b) {
+            if (a.toLowerCase() < b.toLowerCase()) return -1;
+            if (a.toLowerCase() > b.toLowerCase()) return 1;
+            return 0;
+        });
+
+        var deleteRange = new Range(0, 0, 0, 0);
+        for (var i = rows.first; i <= rows.last; i++) {
+            var line = session.getLine(i);
+            deleteRange.start.row = i;
+            deleteRange.end.row = i;
+            deleteRange.end.column = line.length;
+            session.replace(deleteRange, lines[i-rows.first]);
+        }
+    };
+
+    /**
+     * Given the currently selected range, this function either comments all the lines, or uncomments all of them.
+     **/
+    this.toggleCommentLines = function() {
+        var state = this.session.getState(this.getCursorPosition().row);
+        var rows = this.$getSelectedRows();
+        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
+    };
+
+    this.toggleBlockComment = function() {
+        var cursor = this.getCursorPosition();
+        var state = this.session.getState(cursor.row);
+        var range = this.getSelectionRange();
+        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);
+    };
+
+    /**
+     * Works like [[EditSession.getTokenAt]], except it returns a number.
+     * @returns {Number}
+     **/
+    this.getNumberAt = function(row, column) {
+        var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g;
+        _numberRx.lastIndex = 0;
+
+        var s = this.session.getLine(row);
+        while (_numberRx.lastIndex < column) {
+            var m = _numberRx.exec(s);
+            if(m.index <= column && m.index+m[0].length >= column){
+                var number = {
+                    value: m[0],
+                    start: m.index,
+                    end: m.index+m[0].length
+                };
+                return number;
+            }
+        }
+        return null;
+    };
+
+    /**
+     * If the character before the cursor is a number, this functions changes its value by `amount`.
+     * @param {Number} amount The value to change the numeral by (can be negative to decrease value)
+     *
+     **/
+    this.modifyNumber = function(amount) {
+        var row = this.selection.getCursor().row;
+        var column = this.selection.getCursor().column;
+
+        // get the char before the cursor
+        var charRange = new Range(row, column-1, row, column);
+
+        var c = this.session.getTextRange(charRange);
+        // if the char is a digit
+        if (!isNaN(parseFloat(c)) && isFinite(c)) {
+            // get the whole number the digit is part of
+            var nr = this.getNumberAt(row, column);
+            // if number found
+            if (nr) {
+                var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
+                var decimals = nr.start + nr.value.length - fp;
+
+                var t = parseFloat(nr.value);
+                t *= Math.pow(10, decimals);
+
+
+                if(fp !== nr.end && column < fp){
+                    amount *= Math.pow(10, nr.end - column - 1);
+                } else {
+                    amount *= Math.pow(10, nr.end - column);
+                }
+
+                t += amount;
+                t /= Math.pow(10, decimals);
+                var nnr = t.toFixed(decimals);
+
+                //update number
+                var replaceRange = new Range(row, nr.start, row, nr.end);
+                this.session.replace(replaceRange, nnr);
+
+                //reposition the cursor
+                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
+
+            }
+        } else {
+            this.toggleWord();
+        }
+    };
+
+    this.$toggleWordPairs = [
+        ["first", "last"],
+        ["true", "false"],
+        ["yes", "no"],
+        ["width", "height"],
+        ["top", "bottom"],
+        ["right", "left"],
+        ["on", "off"],
+        ["x", "y"],
+        ["get", "set"],
+        ["max", "min"],
+        ["horizontal", "vertical"],
+        ["show", "hide"],
+        ["add", "remove"],
+        ["up", "down"],
+        ["before", "after"],
+        ["even", "odd"],
+        ["in", "out"],
+        ["inside", "outside"],
+        ["next", "previous"],
+        ["increase", "decrease"],
+        ["attach", "detach"],
+        ["&&", "||"],
+        ["==", "!="]
+    ];
+
+    this.toggleWord = function () {
+        var row = this.selection.getCursor().row;
+        var column = this.selection.getCursor().column;
+        this.selection.selectWord();
+        var currentState = this.getSelectedText();
+        var currWordStart = this.selection.getWordRange().start.column;
+        var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\s/);
+        var delta = column - currWordStart - 1;
+        if (delta < 0) delta = 0;
+        var curLength = 0, itLength = 0;
+        var that = this;
+        if (currentState.match(/[A-Za-z0-9_]+/)) {
+            wordParts.forEach(function (item, i) {
+                itLength = curLength + item.length;
+                if (delta >= curLength && delta <= itLength) {
+                    currentState = item;
+                    that.selection.clearSelection();
+                    that.moveCursorTo(row, curLength + currWordStart);
+                    that.selection.selectTo(row, itLength + currWordStart);
+                }
+                curLength = itLength;
+            });
+        }
+
+        var wordPairs = this.$toggleWordPairs;
+        var reg;
+        for (var i = 0; i < wordPairs.length; i++) {
+            var item = wordPairs[i];
+            for (var j = 0; j <= 1; j++) {
+                var negate = +!j;
+                var firstCondition = currentState.match(new RegExp('^\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\s?$', 'i'));
+                if (firstCondition) {
+                    var secondCondition = currentState.match(new RegExp('([_]|^|\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\s)', 'g'));
+                    if (secondCondition) {
+                        reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) {
+                            var res = item[negate];
+                            if (result.toUpperCase() == result) {
+                                res = res.toUpperCase();
+                            } else if (result.charAt(0).toUpperCase() == result.charAt(0)) {
+                                res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1);
+                            }
+                            return res;
+                        });
+                        this.insert(reg);
+                        reg = "";
+                    }
+                }
+            }
+        }
+    };
+
+    /**
+     * Finds link at defined {row} and {column}
+     * @returns {String}
+     **/
+    this.findLinkAt = function (row, column) {
+        var line = this.session.getLine(row);
+        var wordParts = line.split(/((?:https?|ftp):\/\/[\S]+)/);
+        var columnPosition = column;
+        if (columnPosition < 0) columnPosition = 0;
+        var previousPosition = 0, currentPosition = 0, match;
+        for (let item of wordParts) {
+            currentPosition = previousPosition + item.length;
+            if (columnPosition >= previousPosition && columnPosition <= currentPosition) {
+                if (item.match(/((?:https?|ftp):\/\/[\S]+)/)) {
+                    match = item.replace(/[\s:.,'";}\]]+$/, "");
+                    break;
+                }
+            }
+            previousPosition = currentPosition;
+        }
+        return match;
+    };
+
+    /**
+     * Open valid url under cursor in another tab
+     * @returns {Boolean}
+     **/
+    this.openLink = function () {
+        var cursor =  this.selection.getCursor();
+        var url = this.findLinkAt(cursor.row, cursor.column);
+        if (url)
+            window.open(url, '_blank');
+        return url != null;
+    };
+
+    /**
+     * Removes all the lines in the current selection
+     * @related EditSession.remove
+     **/
+    this.removeLines = function() {
+        var rows = this.$getSelectedRows();
+        this.session.removeFullLines(rows.first, rows.last);
+        this.clearSelection();
+    };
+
+    this.duplicateSelection = function() {
+        var sel = this.selection;
+        var doc = this.session;
+        var range = sel.getRange();
+        var reverse = sel.isBackwards();
+        if (range.isEmpty()) {
+            var row = range.start.row;
+            doc.duplicateLines(row, row);
+        } else {
+            var point = reverse ? range.start : range.end;
+            var endPoint = doc.insert(point, doc.getTextRange(range), false);
+            range.start = point;
+            range.end = endPoint;
+
+            sel.setSelectionRange(range, reverse);
+        }
+    };
+
+    /**
+     * Shifts all the selected lines down one row.
+     *
+     * @returns {Number} On success, it returns -1.
+     * @related EditSession.moveLinesUp
+     **/
+    this.moveLinesDown = function() {
+        this.$moveLines(1, false);
+    };
+
+    /**
+     * Shifts all the selected lines up one row.
+     * @returns {Number} On success, it returns -1.
+     * @related EditSession.moveLinesDown
+     **/
+    this.moveLinesUp = function() {
+        this.$moveLines(-1, false);
+    };
+
+    /**
+     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:
+     * ```json
+     *    { row: newRowLocation, column: newColumnLocation }
+     * ```
+     * @param {Range} fromRange The range of text you want moved within the document
+     * @param {Object} toPosition The location (row and column) where you want to move the text to
+     *
+     * @returns {Range} The new range where the text was moved to.
+     * @related EditSession.moveText
+     **/
+    this.moveText = function(range, toPosition, copy) {
+        return this.session.moveText(range, toPosition, copy);
+    };
+
+    /**
+     * Copies all the selected lines up one row.
+     * @returns {Number} On success, returns 0.
+     *
+     **/
+    this.copyLinesUp = function() {
+        this.$moveLines(-1, true);
+    };
+
+    /**
+     * Copies all the selected lines down one row.
+     * @returns {Number} On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`.
+     * @related EditSession.duplicateLines
+     *
+     **/
+    this.copyLinesDown = function() {
+        this.$moveLines(1, true);
+    };
+
+    /**
+     * for internal use
+     * @ignore
+     *
+     **/
+    this.$moveLines = function(dir, copy) {
+        var rows, moved;
+        var selection = this.selection;
+        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
+            var range = selection.toOrientedRange();
+            rows = this.$getSelectedRows(range);
+            moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);
+            if (copy && dir == -1) moved = 0;
+            range.moveBy(moved, 0);
+            selection.fromOrientedRange(range);
+        } else {
+            var ranges = selection.rangeList.ranges;
+            selection.rangeList.detach(this.session);
+            this.inVirtualSelectionMode = true;
+            
+            var diff = 0;
+            var totalDiff = 0;
+            var l = ranges.length;
+            for (var i = 0; i < l; i++) {
+                var rangeIndex = i;
+                ranges[i].moveBy(diff, 0);
+                rows = this.$getSelectedRows(ranges[i]);
+                var first = rows.first;
+                var last = rows.last;
+                while (++i < l) {
+                    if (totalDiff) ranges[i].moveBy(totalDiff, 0);
+                    var subRows = this.$getSelectedRows(ranges[i]);
+                    if (copy && subRows.first != last)
+                        break;
+                    else if (!copy && subRows.first > last + 1)
+                        break;
+                    last = subRows.last;
+                }
+                i--;
+                diff = this.session.$moveLines(first, last, copy ? 0 : dir);
+                if (copy && dir == -1) rangeIndex = i + 1;
+                while (rangeIndex <= i) {
+                    ranges[rangeIndex].moveBy(diff, 0);
+                    rangeIndex++;
+                }
+                if (!copy) diff = 0;
+                totalDiff += diff;
+            }
+            
+            selection.fromOrientedRange(selection.ranges[0]);
+            selection.rangeList.attach(this.session);
+            this.inVirtualSelectionMode = false;
+        }
+    };
+
+    /**
+     * Returns an object indicating the currently selected rows. The object looks like this:
+     *
+     * ```json
+     * { first: range.start.row, last: range.end.row }
+     * ```
+     *
+     * @returns {Object}
+     **/
+    this.$getSelectedRows = function(range) {
+        range = (range || this.getSelectionRange()).collapseRows();
+
+        return {
+            first: this.session.getRowFoldStart(range.start.row),
+            last: this.session.getRowFoldEnd(range.end.row)
+        };
+    };
+
+    this.onCompositionStart = function(compositionState) {
+        this.renderer.showComposition(compositionState);
+    };
+
+    this.onCompositionUpdate = function(text) {
+        this.renderer.setCompositionText(text);
+    };
+
+    this.onCompositionEnd = function() {
+        this.renderer.hideComposition();
+    };
+
+    /**
+     * {:VirtualRenderer.getFirstVisibleRow}
+     *
+     * @returns {Number}
+     * @related VirtualRenderer.getFirstVisibleRow
+     **/
+    this.getFirstVisibleRow = function() {
+        return this.renderer.getFirstVisibleRow();
+    };
+
+    /**
+     * {:VirtualRenderer.getLastVisibleRow}
+     *
+     * @returns {Number}
+     * @related VirtualRenderer.getLastVisibleRow
+     **/
+    this.getLastVisibleRow = function() {
+        return this.renderer.getLastVisibleRow();
+    };
+
+    /**
+     * Indicates if the row is currently visible on the screen.
+     * @param {Number} row The row to check
+     *
+     * @returns {Boolean}
+     **/
+    this.isRowVisible = function(row) {
+        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
+    };
+
+    /**
+     * Indicates if the entire row is currently visible on the screen.
+     * @param {Number} row The row to check
+     *
+     *
+     * @returns {Boolean}
+     **/
+    this.isRowFullyVisible = function(row) {
+        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
+    };
+
+    /**
+     * Returns the number of currently visible rows.
+     * @returns {Number}
+     **/
+    this.$getVisibleRowCount = function() {
+        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
+    };
+
+    this.$moveByPage = function(dir, select) {
+        var renderer = this.renderer;
+        var config = this.renderer.layerConfig;
+        var rows = dir * Math.floor(config.height / config.lineHeight);
+
+        if (select === true) {
+            this.selection.$moveSelection(function(){
+                this.moveCursorBy(rows, 0);
+            });
+        } else if (select === false) {
+            this.selection.moveCursorBy(rows, 0);
+            this.selection.clearSelection();
+        }
+
+        var scrollTop = renderer.scrollTop;
+
+        renderer.scrollBy(0, rows * config.lineHeight);
+        if (select != null)
+            renderer.scrollCursorIntoView(null, 0.5);
+
+        renderer.animateScrolling(scrollTop);
+    };
+
+    /**
+     * Selects the text from the current position of the document until where a "page down" finishes.
+     **/
+    this.selectPageDown = function() {
+        this.$moveByPage(1, true);
+    };
+
+    /**
+     * Selects the text from the current position of the document until where a "page up" finishes.
+     **/
+    this.selectPageUp = function() {
+        this.$moveByPage(-1, true);
+    };
+
+    /**
+     * Shifts the document to wherever "page down" is, as well as moving the cursor position.
+     **/
+    this.gotoPageDown = function() {
+       this.$moveByPage(1, false);
+    };
+
+    /**
+     * Shifts the document to wherever "page up" is, as well as moving the cursor position.
+     **/
+    this.gotoPageUp = function() {
+        this.$moveByPage(-1, false);
+    };
+
+    /**
+     * Scrolls the document to wherever "page down" is, without changing the cursor position.
+     **/
+    this.scrollPageDown = function() {
+        this.$moveByPage(1);
+    };
+
+    /**
+     * Scrolls the document to wherever "page up" is, without changing the cursor position.
+     **/
+    this.scrollPageUp = function() {
+        this.$moveByPage(-1);
+    };
+
+    /**
+     * Moves the editor to the specified row.
+     * @related VirtualRenderer.scrollToRow
+     **/
+    this.scrollToRow = function(row) {
+        this.renderer.scrollToRow(row);
+    };
+
+    /**
+     * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).
+     * @param {Number} line The line to scroll to
+     * @param {Boolean} center If `true`
+     * @param {Boolean} animate If `true` animates scrolling
+     * @param {Function} callback Function to be called when the animation has finished
+     *
+     *
+     * @related VirtualRenderer.scrollToLine
+     **/
+    this.scrollToLine = function(line, center, animate, callback) {
+        this.renderer.scrollToLine(line, center, animate, callback);
+    };
+
+    /**
+     * Attempts to center the current selection on the screen.
+     **/
+    this.centerSelection = function() {
+        var range = this.getSelectionRange();
+        var pos = {
+            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
+            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
+        };
+        this.renderer.alignCursor(pos, 0.5);
+    };
+
+    /**
+     * Gets the current position of the cursor.
+     * @returns {Object} An object that looks something like this:
+     *
+     * ```json
+     * { row: currRow, column: currCol }
+     * ```
+     *
+     * @related Selection.getCursor
+     **/
+    this.getCursorPosition = function() {
+        return this.selection.getCursor();
+    };
+
+    /**
+     * Returns the screen position of the cursor.
+     * @returns {Number}
+     * @related EditSession.documentToScreenPosition
+     **/
+    this.getCursorPositionScreen = function() {
+        return this.session.documentToScreenPosition(this.getCursorPosition());
+    };
+
+    /**
+     * {:Selection.getRange}
+     * @returns {Range}
+     * @related Selection.getRange
+     **/
+    this.getSelectionRange = function() {
+        return this.selection.getRange();
+    };
+
+
+    /**
+     * Selects all the text in editor.
+     * @related Selection.selectAll
+     **/
+    this.selectAll = function() {
+        this.selection.selectAll();
+    };
+
+    /**
+     * {:Selection.clearSelection}
+     * @related Selection.clearSelection
+     **/
+    this.clearSelection = function() {
+        this.selection.clearSelection();
+    };
+
+    /**
+     * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.
+     * @param {Number} row The new row number
+     * @param {Number} column The new column number
+     *
+     *
+     * @related Selection.moveCursorTo
+     **/
+    this.moveCursorTo = function(row, column) {
+        this.selection.moveCursorTo(row, column);
+    };
+
+    /**
+     * Moves the cursor to the position indicated by `pos.row` and `pos.column`.
+     * @param {Object} pos An object with two properties, row and column
+     *
+     *
+     * @related Selection.moveCursorToPosition
+     **/
+    this.moveCursorToPosition = function(pos) {
+        this.selection.moveCursorToPosition(pos);
+    };
+
+    /**
+     * Moves the cursor's row and column to the next matching bracket or HTML tag.
+     *
+     **/
+    this.jumpToMatching = function (select, expand) {
+        var cursor = this.getCursorPosition();
+        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
+        var prevToken = iterator.getCurrentToken();
+        var tokenCount = 0;
+        if (prevToken && prevToken.type.indexOf('tag-name') !== -1) {
+            prevToken = iterator.stepBackward();
+        }
+        var token = prevToken || iterator.stepForward();
+
+        if (!token) return;
+
+        //get next closing tag or bracket
+        var matchType;
+        var found = false;
+        var depth = {};
+        var i = cursor.column - token.start;
+        var bracketType;
+        var brackets = {
+            ")": "(",
+            "(": "(",
+            "]": "[",
+            "[": "[",
+            "{": "{",
+            "}": "{"
+        };
+
+        do {
+            if (token.value.match(/[{}()\[\]]/g)) {
+                for (; i < token.value.length && !found; i++) {
+                    if (!brackets[token.value[i]]) {
+                        continue;
+                    }
+
+                    bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
+
+                    if (isNaN(depth[bracketType])) {
+                        depth[bracketType] = 0;
+                    }
+
+                    switch (token.value[i]) {
+                        case '(':
+                        case '[':
+                        case '{':
+                            depth[bracketType]++;
+                            break;
+                        case ')':
+                        case ']':
+                        case '}':
+                            depth[bracketType]--;
+
+                            if (depth[bracketType] === -1) {
+                                matchType = 'bracket';
+                                found = true;
+                            }
+                            break;
+                    }
+                }
+            }
+            else if (token.type.indexOf('tag-name') !== -1) {
+                if (isNaN(depth[token.value])) {
+                    depth[token.value] = 0;
+                }
+
+                if (prevToken.value === '<' && tokenCount > 1) {
+                    depth[token.value]++;
+                }
+                else if (prevToken.value === '= 0; --i) {
+            if(this.$tryReplace(ranges[i], replacement)) {
+                replaced++;
+            }
+        }
+
+        this.selection.setSelectionRange(selection);
+
+        return replaced;
+    };
+
+    this.$tryReplace = function(range, replacement) {
+        var input = this.session.getTextRange(range);
+        replacement = this.$search.replace(input, replacement);
+        if (replacement !== null) {
+            range.end = this.session.replace(range, replacement);
+            return range;
+        } else {
+            return null;
+        }
+    };
+
+    /**
+     * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].
+     * @related Search.getOptions
+     * @returns {Object}
+     **/
+    this.getLastSearchOptions = function() {
+        return this.$search.getOptions();
+    };
+
+    /**
+     * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].
+     * @param {String} needle The text to search for (optional)
+     * @param {Object} options An object defining various search properties
+     * @param {Boolean} animate If `true` animate scrolling
+     *
+     *
+     * @related Search.find
+     **/
+    this.find = function(needle, options, animate) {
+        if (!options)
+            options = {};
+
+        if (typeof needle == "string" || needle instanceof RegExp)
+            options.needle = needle;
+        else if (typeof needle == "object")
+            oop.mixin(options, needle);
+
+        var range = this.selection.getRange();
+        if (options.needle == null) {
+            needle = this.session.getTextRange(range)
+                || this.$search.$options.needle;
+            if (!needle) {
+                range = this.session.getWordRange(range.start.row, range.start.column);
+                needle = this.session.getTextRange(range);
+            }
+            this.$search.set({needle: needle});
+        }
+
+        this.$search.set(options);
+        if (!options.start)
+            this.$search.set({start: range});
+
+        var newRange = this.$search.find(this.session);
+        if (options.preventScroll)
+            return newRange;
+        if (newRange) {
+            this.revealRange(newRange, animate);
+            return newRange;
+        }
+        // clear selection if nothing is found
+        if (options.backwards)
+            range.start = range.end;
+        else
+            range.end = range.start;
+        this.selection.setRange(range);
+    };
+
+    /**
+     * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].
+     * @param {Object} options search options
+     * @param {Boolean} animate If `true` animate scrolling
+     *
+     *
+     * @related Editor.find
+     **/
+    this.findNext = function(options, animate) {
+        this.find({skipCurrent: true, backwards: false}, options, animate);
+    };
+
+    /**
+     * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].
+     * @param {Object} options search options
+     * @param {Boolean} animate If `true` animate scrolling
+     *
+     *
+     * @related Editor.find
+     **/
+    this.findPrevious = function(options, animate) {
+        this.find(options, {skipCurrent: true, backwards: true}, animate);
+    };
+
+    this.revealRange = function(range, animate) {
+        this.session.unfold(range);
+        this.selection.setSelectionRange(range);
+
+        var scrollTop = this.renderer.scrollTop;
+        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
+        if (animate !== false)
+            this.renderer.animateScrolling(scrollTop);
+    };
+
+    /**
+     * {:UndoManager.undo}
+     * @related UndoManager.undo
+     **/
+    this.undo = function() {
+        this.session.getUndoManager().undo(this.session);
+        this.renderer.scrollCursorIntoView(null, 0.5);
+    };
+
+    /**
+     * {:UndoManager.redo}
+     * @related UndoManager.redo
+     **/
+    this.redo = function() {
+        this.session.getUndoManager().redo(this.session);
+        this.renderer.scrollCursorIntoView(null, 0.5);
+    };
+
+    /**
+     *
+     * Cleans up the entire editor.
+     **/
+    this.destroy = function() {
+        if (this.$toDestroy) {
+            this.$toDestroy.forEach(function(el) {
+                el.destroy();
+            });
+            this.$toDestroy = null;
+        }
+        if (this.$mouseHandler)
+            this.$mouseHandler.destroy();
+        this.renderer.destroy();
+        this._signal("destroy", this);
+        if (this.session)
+            this.session.destroy();
+        if (this._$emitInputEvent)
+            this._$emitInputEvent.cancel();
+        this.removeAllListeners();
+    };
+
+    /**
+     * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element
+     * @param {Boolean} enable default true
+     **/
+    this.setAutoScrollEditorIntoView = function(enable) {
+        if (!enable)
+            return;
+        var rect;
+        var self = this;
+        var shouldScroll = false;
+        if (!this.$scrollAnchor)
+            this.$scrollAnchor = document.createElement("div");
+        var scrollAnchor = this.$scrollAnchor;
+        scrollAnchor.style.cssText = "position:absolute";
+        this.container.insertBefore(scrollAnchor, this.container.firstChild);
+        var onChangeSelection = this.on("changeSelection", function() {
+            shouldScroll = true;
+        });
+        // needed to not trigger sync reflow
+        var onBeforeRender = this.renderer.on("beforeRender", function() {
+            if (shouldScroll)
+                rect = self.renderer.container.getBoundingClientRect();
+        });
+        var onAfterRender = this.renderer.on("afterRender", function() {
+            if (shouldScroll && rect && (self.isFocused()
+                || self.searchBox && self.searchBox.isFocused())
+            ) {
+                var renderer = self.renderer;
+                var pos = renderer.$cursorLayer.$pixelPos;
+                var config = renderer.layerConfig;
+                var top = pos.top - config.offset;
+                if (pos.top >= 0 && top + rect.top < 0) {
+                    shouldScroll = true;
+                } else if (pos.top < config.height &&
+                    pos.top + rect.top + config.lineHeight > window.innerHeight) {
+                    shouldScroll = false;
+                } else {
+                    shouldScroll = null;
+                }
+                if (shouldScroll != null) {
+                    scrollAnchor.style.top = top + "px";
+                    scrollAnchor.style.left = pos.left + "px";
+                    scrollAnchor.style.height = config.lineHeight + "px";
+                    scrollAnchor.scrollIntoView(shouldScroll);
+                }
+                shouldScroll = rect = null;
+            }
+        });
+        this.setAutoScrollEditorIntoView = function(enable) {
+            if (enable)
+                return;
+            delete this.setAutoScrollEditorIntoView;
+            this.off("changeSelection", onChangeSelection);
+            this.renderer.off("afterRender", onAfterRender);
+            this.renderer.off("beforeRender", onBeforeRender);
+        };
+    };
+
+
+    this.$resetCursorStyle = function() {
+        var style = this.$cursorStyle || "ace";
+        var cursorLayer = this.renderer.$cursorLayer;
+        if (!cursorLayer)
+            return;
+        cursorLayer.setSmoothBlinking(/smooth/.test(style));
+        cursorLayer.isBlinking = !this.$readOnly && style != "wide";
+        dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style));
+    };
+
+    /**
+     * opens a prompt displaying message
+     **/
+    this.prompt = function(message, options, callback) {
+        var editor = this;
+        config.loadModule("ace/ext/prompt", function (module) {
+            module.prompt(editor, message, options, callback);
+        });
+    };
+
+}).call(Editor.prototype);
+
+
+
+config.defineOptions(Editor.prototype, "editor", {
+    selectionStyle: {
+        set: function(style) {
+            this.onSelectionChange();
+            this._signal("changeSelectionStyle", {data: style});
+        },
+        initialValue: "line"
+    },
+    highlightActiveLine: {
+        set: function() {this.$updateHighlightActiveLine();},
+        initialValue: true
+    },
+    highlightSelectedWord: {
+        set: function(shouldHighlight) {this.$onSelectionChange();},
+        initialValue: true
+    },
+    readOnly: {
+        set: function(readOnly) {
+            this.textInput.setReadOnly(readOnly);
+            this.$resetCursorStyle(); 
+        },
+        initialValue: false
+    },
+    copyWithEmptySelection: {
+        set: function(value) {
+            this.textInput.setCopyWithEmptySelection(value);
+        },
+        initialValue: false
+    },
+    cursorStyle: {
+        set: function(val) { this.$resetCursorStyle(); },
+        values: ["ace", "slim", "smooth", "wide"],
+        initialValue: "ace"
+    },
+    mergeUndoDeltas: {
+        values: [false, true, "always"],
+        initialValue: true
+    },
+    behavioursEnabled: {initialValue: true},
+    wrapBehavioursEnabled: {initialValue: true},
+    enableAutoIndent: {initialValue: true},
+    autoScrollEditorIntoView: {
+        set: function(val) {this.setAutoScrollEditorIntoView(val);}
+    },
+    keyboardHandler: {
+        set: function(val) { this.setKeyboardHandler(val); },
+        get: function() { return this.$keybindingId; },
+        handlesSet: true
+    },
+    value: {
+        set: function(val) { this.session.setValue(val); },
+        get: function() { return this.getValue(); },
+        handlesSet: true,
+        hidden: true
+    },
+    session: {
+        set: function(val) { this.setSession(val); },
+        get: function() { return this.session; },
+        handlesSet: true,
+        hidden: true
+    },
+    
+    showLineNumbers: {
+        set: function(show) {
+            this.renderer.$gutterLayer.setShowLineNumbers(show);
+            this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER);
+            if (show && this.$relativeLineNumbers)
+                relativeNumberRenderer.attach(this);
+            else
+                relativeNumberRenderer.detach(this);
+        },
+        initialValue: true
+    },
+    relativeLineNumbers: {
+        set: function(value) {
+            if (this.$showLineNumbers && value)
+                relativeNumberRenderer.attach(this);
+            else
+                relativeNumberRenderer.detach(this);
+        }
+    },
+    placeholder: {
+        set: function(message) {
+            if (!this.$updatePlaceholder) {
+                this.$updatePlaceholder = function() {
+                    var value = this.session && (this.renderer.$composition || this.getValue());
+                    if (value && this.renderer.placeholderNode) {
+                        this.renderer.off("afterRender", this.$updatePlaceholder);
+                        dom.removeCssClass(this.container, "ace_hasPlaceholder");
+                        this.renderer.placeholderNode.remove();
+                        this.renderer.placeholderNode = null;
+                    } else if (!value && !this.renderer.placeholderNode) {
+                        this.renderer.on("afterRender", this.$updatePlaceholder);
+                        dom.addCssClass(this.container, "ace_hasPlaceholder");
+                        var el = dom.createElement("div");
+                        el.className = "ace_placeholder";
+                        el.textContent = this.$placeholder || "";
+                        this.renderer.placeholderNode = el;
+                        this.renderer.content.appendChild(this.renderer.placeholderNode);
+                    } else if (!value && this.renderer.placeholderNode) {
+                        this.renderer.placeholderNode.textContent = this.$placeholder || "";
+                    }
+                }.bind(this);
+                this.on("input", this.$updatePlaceholder);
+            }
+            this.$updatePlaceholder();
+        }
+    },
+    customScrollbar: "renderer",
+    hScrollBarAlwaysVisible: "renderer",
+    vScrollBarAlwaysVisible: "renderer",
+    highlightGutterLine: "renderer",
+    animatedScroll: "renderer",
+    showInvisibles: "renderer",
+    showPrintMargin: "renderer",
+    printMarginColumn: "renderer",
+    printMargin: "renderer",
+    fadeFoldWidgets: "renderer",
+    showFoldWidgets: "renderer",
+    displayIndentGuides: "renderer",
+    highlightIndentGuides: "renderer",
+    showGutter: "renderer",
+    fontSize: "renderer",
+    fontFamily: "renderer",
+    maxLines: "renderer",
+    minLines: "renderer",
+    scrollPastEnd: "renderer",
+    fixedWidthGutter: "renderer",
+    theme: "renderer",
+    hasCssTransforms: "renderer",
+    maxPixelHeight: "renderer",
+    useTextareaForIME: "renderer",
+
+    scrollSpeed: "$mouseHandler",
+    dragDelay: "$mouseHandler",
+    dragEnabled: "$mouseHandler",
+    focusTimeout: "$mouseHandler",
+    tooltipFollowsMouse: "$mouseHandler",
+
+    firstLineNumber: "session",
+    overwrite: "session",
+    newLineMode: "session",
+    useWorker: "session",
+    useSoftTabs: "session",
+    navigateWithinSoftTabs: "session",
+    tabSize: "session",
+    wrap: "session",
+    indentedSoftWrap: "session",
+    foldStyle: "session",
+    mode: "session"
+});
+
+
+var relativeNumberRenderer = {
+    getText: function(session, row) {
+        return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? "\xb7" : ""))) + "";
+    },
+    getWidth: function(session, lastLineNumber, config) {
+        return Math.max(
+            lastLineNumber.toString().length,
+            (config.lastRow + 1).toString().length,
+            2
+        ) * config.characterWidth;
+    },
+    update: function(e, editor) {
+        editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER);
+    },
+    attach: function(editor) {
+        editor.renderer.$gutterLayer.$renderer = this;
+        editor.on("changeSelection", this.update);
+        this.update(null, editor);
+    },
+    detach: function(editor) {
+        if (editor.renderer.$gutterLayer.$renderer == this)
+            editor.renderer.$gutterLayer.$renderer = null;
+        editor.off("changeSelection", this.update);
+        this.update(null, editor);
+    }
+};
+
+exports.Editor = Editor;
diff --git a/demo/diff/examples/editor.17.js b/demo/diff/examples/editor.17.js
new file mode 100644
index 00000000000..474e8448b24
--- /dev/null
+++ b/demo/diff/examples/editor.17.js
@@ -0,0 +1,2983 @@
+"use strict";
+
+var oop = require("./lib/oop");
+var dom = require("./lib/dom");
+var lang = require("./lib/lang");
+var useragent = require("./lib/useragent");
+var TextInput = require("./keyboard/textinput").TextInput;
+var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
+var FoldHandler = require("./mouse/fold_handler").FoldHandler;
+var KeyBinding = require("./keyboard/keybinding").KeyBinding;
+var EditSession = require("./edit_session").EditSession;
+var Search = require("./search").Search;
+var Range = require("./range").Range;
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+var CommandManager = require("./commands/command_manager").CommandManager;
+var defaultCommands = require("./commands/default_commands").commands;
+var config = require("./config");
+var TokenIterator = require("./token_iterator").TokenIterator;
+var LineWidgets = require("./line_widgets").LineWidgets;
+
+var clipboard = require("./clipboard");
+var keys = require('./lib/keys');
+
+/**
+ * The main entry point into the Ace functionality.
+ *
+ * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.
+ *
+ * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.
+ **/
+class Editor {
+    /**
+     * Creates a new `Editor` object.
+     *
+     * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything
+     * @param {EditSession} session The `EditSession` to refer to
+     **/
+    constructor(renderer, session, options) {
+        this.$toDestroy = [];
+        var container = renderer.getContainerElement();
+        this.container = container;
+        this.renderer = renderer;
+        this.id = "editor" + (++Editor.$uid);
+
+        this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
+        if (typeof document == "object") {
+            this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
+            this.renderer.textarea = this.textInput.getElement();
+            // TODO detect touch event support
+            this.$mouseHandler = new MouseHandler(this);
+            new FoldHandler(this);
+        }
+
+        this.keyBinding = new KeyBinding(this);
+
+        this.$search = new Search().set({
+            wrap: true
+        });
+
+        this.$historyTracker = this.$historyTracker.bind(this);
+        this.commands.on("exec", this.$historyTracker);
+
+        this.$initOperationListeners();
+
+        this._$emitInputEvent = lang.delayedCall(function() {
+            this._signal("input", {});
+            if (this.session && !this.session.destroyed)
+                this.session.bgTokenizer.scheduleStart();
+        }.bind(this));
+
+        this.on("change", function(_, _self) {
+            _self._$emitInputEvent.schedule(31);
+        });
+
+        this.setSession(session || options && options.session || new EditSession(""));
+        config.resetOptions(this);
+        if (options)
+            this.setOptions(options);
+        config._signal("editor", this);
+    }
+
+    $initOperationListeners() {
+        this.commands.on("exec", this.startOperation.bind(this), true);
+        this.commands.on("afterExec", this.endOperation.bind(this), true);
+
+        this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this, true));
+        
+        // todo: add before change events?
+        this.on("change", function() {
+            if (!this.curOp) {
+                this.startOperation();
+                this.curOp.selectionBefore = this.$lastSel;
+            }
+            this.curOp.docChanged = true;
+        }.bind(this), true);
+        
+        this.on("changeSelection", function() {
+            if (!this.curOp) {
+                this.startOperation();
+                this.curOp.selectionBefore = this.$lastSel;
+            }
+            this.curOp.selectionChanged = true;
+        }.bind(this), true);
+    }
+
+    startOperation(commandEvent) {
+        if (this.curOp) {
+            if (!commandEvent || this.curOp.command)
+                return;
+            this.prevOp = this.curOp;
+        }
+        if (!commandEvent) {
+            this.previousCommand = null;
+            commandEvent = {};
+        }
+
+        this.$opResetTimer.schedule();
+        this.curOp = this.session.curOp = {
+            command: commandEvent.command || {},
+            args: commandEvent.args,
+            scrollTop: this.renderer.scrollTop
+        };
+        this.curOp.selectionBefore = this.selection.toJSON();
+    }
+
+    endOperation(e) {
+        if (this.curOp && this.session) {
+            if (e && e.returnValue === false || !this.session)
+                return (this.curOp = null);
+            if (e == true && this.curOp.command && this.curOp.command.name == "mouse")
+                return;
+            this._signal("beforeEndOperation");
+            if (!this.curOp) return;
+            var command = this.curOp.command;
+            var scrollIntoView = command && command.scrollIntoView;
+            if (scrollIntoView) {
+                switch (scrollIntoView) {
+                    case "center-animate":
+                        scrollIntoView = "animate";
+                        /* fall through */
+                    case "center":
+                        this.renderer.scrollCursorIntoView(null, 0.5);
+                        break;
+                    case "animate":
+                    case "cursor":
+                        this.renderer.scrollCursorIntoView();
+                        break;
+                    case "selectionPart":
+                        var range = this.selection.getRange();
+                        var config = this.renderer.layerConfig;
+                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {
+                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);
+                        }
+                        break;
+                    default:
+                        break;
+                }
+                if (scrollIntoView == "animate")
+                    this.renderer.animateScrolling(this.curOp.scrollTop);
+            }
+            var sel = this.selection.toJSON();
+            this.curOp.selectionAfter = sel;
+            this.$lastSel = this.selection.toJSON();
+            
+            // console.log(this.$lastSel+"  endOP")
+            this.session.getUndoManager().addSelection(sel);
+            this.prevOp = this.curOp;
+            this.curOp = null;
+        }
+    }
+    
+    $historyTracker(e) {
+        if (!this.$mergeUndoDeltas)
+            return;
+
+        var prev = this.prevOp;
+        var mergeableCommands = this.$mergeableCommands;
+        // previous command was the same
+        var shouldMerge = prev.command && (e.command.name == prev.command.name);
+        if (e.command.name == "insertstring") {
+            var text = e.args;
+            if (this.mergeNextCommand === undefined)
+                this.mergeNextCommand = true;
+
+            shouldMerge = shouldMerge
+                && this.mergeNextCommand // previous command allows to coalesce with
+                && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type
+
+            this.mergeNextCommand = true;
+        } else {
+            shouldMerge = shouldMerge
+                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable
+        }
+
+        if (
+            this.$mergeUndoDeltas != "always"
+            && Date.now() - this.sequenceStartTime > 2000
+        ) {
+            shouldMerge = false; // the sequence is too long
+        }
+
+        if (shouldMerge)
+            this.session.mergeUndoDeltas = true;
+        else if (mergeableCommands.indexOf(e.command.name) !== -1)
+            this.sequenceStartTime = Date.now();
+    }
+
+    /**
+     * Sets a new key handler, such as "vim" or "windows".
+     * @param {String} keyboardHandler The new key handler
+     *
+     **/
+    setKeyboardHandler(keyboardHandler, cb) {
+        if (keyboardHandler && typeof keyboardHandler === "string" && keyboardHandler != "ace") {
+            this.$keybindingId = keyboardHandler;
+            var _self = this;
+            config.loadModule(["keybinding", keyboardHandler], function(module) {
+                if (_self.$keybindingId == keyboardHandler)
+                    _self.keyBinding.setKeyboardHandler(module && module.handler);
+                cb && cb();
+            });
+        } else {
+            this.$keybindingId = null;
+            this.keyBinding.setKeyboardHandler(keyboardHandler);
+            cb && cb();
+        }
+    }
+
+    /**
+     * Returns the keyboard handler, such as "vim" or "windows".
+     *
+     * @returns {String}
+     *
+     **/
+    getKeyboardHandler() {
+        return this.keyBinding.getKeyboardHandler();
+    }
+
+
+    /**
+     * Emitted whenever the [[EditSession]] changes.
+     * @event changeSession
+     * @param {Object} e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s.
+     *
+     **/
+    /**
+     * Sets a new editsession to use. This method also emits the `'changeSession'` event.
+     * @param {EditSession} session The new session to use
+     *
+     **/
+    setSession(session) {
+        if (this.session == session)
+            return;
+        
+        // make sure operationEnd events are not emitted to wrong session
+        if (this.curOp) this.endOperation();
+        this.curOp = {};
+
+        var oldSession = this.session;
+        if (oldSession) {
+            this.session.off("change", this.$onDocumentChange);
+            this.session.off("changeMode", this.$onChangeMode);
+            this.session.off("tokenizerUpdate", this.$onTokenizerUpdate);
+            this.session.off("changeTabSize", this.$onChangeTabSize);
+            this.session.off("changeWrapLimit", this.$onChangeWrapLimit);
+            this.session.off("changeWrapMode", this.$onChangeWrapMode);
+            this.session.off("changeFold", this.$onChangeFold);
+            this.session.off("changeFrontMarker", this.$onChangeFrontMarker);
+            this.session.off("changeBackMarker", this.$onChangeBackMarker);
+            this.session.off("changeBreakpoint", this.$onChangeBreakpoint);
+            this.session.off("changeAnnotation", this.$onChangeAnnotation);
+            this.session.off("changeOverwrite", this.$onCursorChange);
+            this.session.off("changeScrollTop", this.$onScrollTopChange);
+            this.session.off("changeScrollLeft", this.$onScrollLeftChange);
+
+            var selection = this.session.getSelection();
+            selection.off("changeCursor", this.$onCursorChange);
+            selection.off("changeSelection", this.$onSelectionChange);
+        }
+
+        this.session = session;
+        if (session) {
+            this.$onDocumentChange = this.onDocumentChange.bind(this);
+            session.on("change", this.$onDocumentChange);
+            this.renderer.setSession(session);
+    
+            this.$onChangeMode = this.onChangeMode.bind(this);
+            session.on("changeMode", this.$onChangeMode);
+    
+            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
+            session.on("tokenizerUpdate", this.$onTokenizerUpdate);
+    
+            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
+            session.on("changeTabSize", this.$onChangeTabSize);
+    
+            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
+            session.on("changeWrapLimit", this.$onChangeWrapLimit);
+    
+            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
+            session.on("changeWrapMode", this.$onChangeWrapMode);
+    
+            this.$onChangeFold = this.onChangeFold.bind(this);
+            session.on("changeFold", this.$onChangeFold);
+    
+            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
+            this.session.on("changeFrontMarker", this.$onChangeFrontMarker);
+    
+            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
+            this.session.on("changeBackMarker", this.$onChangeBackMarker);
+    
+            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
+            this.session.on("changeBreakpoint", this.$onChangeBreakpoint);
+    
+            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
+            this.session.on("changeAnnotation", this.$onChangeAnnotation);
+    
+            this.$onCursorChange = this.onCursorChange.bind(this);
+            this.session.on("changeOverwrite", this.$onCursorChange);
+    
+            this.$onScrollTopChange = this.onScrollTopChange.bind(this);
+            this.session.on("changeScrollTop", this.$onScrollTopChange);
+    
+            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
+            this.session.on("changeScrollLeft", this.$onScrollLeftChange);
+    
+            this.selection = session.getSelection();
+            this.selection.on("changeCursor", this.$onCursorChange);
+    
+            this.$onSelectionChange = this.onSelectionChange.bind(this);
+            this.selection.on("changeSelection", this.$onSelectionChange);
+    
+            this.onChangeMode();
+    
+            this.onCursorChange();
+    
+            this.onScrollTopChange();
+            this.onScrollLeftChange();
+            this.onSelectionChange();
+            this.onChangeFrontMarker();
+            this.onChangeBackMarker();
+            this.onChangeBreakpoint();
+            this.onChangeAnnotation();
+            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
+            this.renderer.updateFull();
+        } else {
+            this.selection = null;
+            this.renderer.setSession(session);
+        }
+
+        this._signal("changeSession", {
+            session: session,
+            oldSession: oldSession
+        });
+        
+        this.curOp = null;
+        
+        oldSession && oldSession._signal("changeEditor", {oldEditor: this});
+        session && session._signal("changeEditor", {editor: this});
+        
+        if (session && !session.destroyed)
+            session.bgTokenizer.scheduleStart();
+    }
+
+    /**
+     * Returns the current session being used.
+     * @returns {EditSession}
+     **/
+    getSession() {
+        return this.session;
+    }
+
+    /**
+     * Sets the current document to `val`.
+     * @param {String} val The new value to set for the document
+     * @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
+     *
+     * @returns {String} The current document value
+     * @related Document.setValue
+     **/
+    setValue(val, cursorPos) {
+        this.session.doc.setValue(val);
+
+        if (!cursorPos)
+            this.selectAll();
+        else if (cursorPos == 1)
+            this.navigateFileEnd();
+        else if (cursorPos == -1)
+            this.navigateFileStart();
+
+        return val;
+    }
+
+    /**
+     * Returns the current session's content.
+     *
+     * @returns {String}
+     * @related EditSession.getValue
+     **/
+    getValue() {
+        return this.session.getValue();
+    }
+
+    /**
+     *
+     * Returns the currently highlighted selection.
+     * @returns {Selection} The selection object
+     **/
+    getSelection() {
+        return this.selection;
+    }
+
+    /**
+     * {:VirtualRenderer.onResize}
+     * @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed
+     *
+     *
+     * @related VirtualRenderer.onResize
+     **/
+    resize(force) {
+        this.renderer.onResize(force);
+    }
+
+    /**
+     * {:VirtualRenderer.setTheme}
+     * @param {String} theme The path to a theme
+     * @param {Function} cb optional callback called when theme is loaded
+     **/
+    setTheme(theme, cb) {
+        this.renderer.setTheme(theme, cb);
+    }
+
+    /**
+     * {:VirtualRenderer.getTheme}
+     *
+     * @returns {String} The set theme
+     * @related VirtualRenderer.getTheme
+     **/
+    getTheme() {
+        return this.renderer.getTheme();
+    }
+
+    /**
+     * {:VirtualRenderer.setStyle}
+     * @param {String} style A class name
+     *
+     *
+     * @related VirtualRenderer.setStyle
+     **/
+    setStyle(style) {
+        this.renderer.setStyle(style);
+    }
+
+    /**
+     * {:VirtualRenderer.unsetStyle}
+     * @related VirtualRenderer.unsetStyle
+     **/
+    unsetStyle(style) {
+        this.renderer.unsetStyle(style);
+    }
+
+    /**
+     * Gets the current font size of the editor text.
+     */
+    getFontSize() {
+        return this.getOption("fontSize") ||
+           dom.computedStyle(this.container).fontSize;
+    }
+
+    /**
+     * Set a new font size (in pixels) for the editor text.
+     * @param {String} size A font size ( _e.g._ "12px")
+     *
+     *
+     **/
+    setFontSize(size) {
+        this.setOption("fontSize", size);
+    }
+
+    $highlightBrackets() {
+        if (this.$highlightPending) {
+            return;
+        }
+
+        // perform highlight async to not block the browser during navigation
+        var self = this;
+        this.$highlightPending = true;
+        setTimeout(function () {
+            self.$highlightPending = false;
+            var session = self.session;
+            if (!session || session.destroyed) return;
+            if (session.$bracketHighlight) {
+                session.$bracketHighlight.markerIds.forEach(function(id) {
+                    session.removeMarker(id);
+                });
+                session.$bracketHighlight = null;
+            }
+            var pos = self.getCursorPosition();
+            var handler = self.getKeyboardHandler();
+            var isBackwards = handler && handler.$getDirectionForHighlight && handler.$getDirectionForHighlight(self);
+            var ranges = session.getMatchingBracketRanges(pos, isBackwards);
+
+            if (!ranges) {
+                var iterator = new TokenIterator(session, pos.row, pos.column);
+                var token = iterator.getCurrentToken();
+
+                if (token && /\b(?:tag-open|tag-name)/.test(token.type)) {
+                    var tagNamesRanges = session.getMatchingTags(pos);
+                    if (tagNamesRanges) ranges = [tagNamesRanges.openTagName, tagNamesRanges.closeTagName];
+                }
+            }
+            if (!ranges && session.$mode.getMatching)
+                ranges = session.$mode.getMatching(self.session);
+            if (!ranges) {
+                if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();
+                return;
+            }
+
+            var markerType = "ace_bracket";
+            if (!Array.isArray(ranges)) {
+                ranges = [ranges];
+            } else if (ranges.length == 1) {
+                markerType = "ace_error_bracket";
+            }
+
+            // show adjacent ranges as one
+            if (ranges.length == 2) {
+                if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)
+                    ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];
+                else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)
+                    ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];
+            }
+
+            session.$bracketHighlight = {
+                ranges: ranges,
+                markerIds: ranges.map(function(range) {
+                    return session.addMarker(range, markerType, "text");
+                })
+            };
+            if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();
+        }, 50);
+    }
+
+    /**
+     *
+     * Brings the current `textInput` into focus.
+     **/
+    focus() {
+        this.textInput.focus();
+    }
+
+    /**
+     * Returns `true` if the current `textInput` is in focus.
+     * @return {Boolean}
+     **/
+    isFocused() {
+        return this.textInput.isFocused();
+    }
+
+    /**
+     *
+     * Blurs the current `textInput`.
+     **/
+    blur() {
+        this.textInput.blur();
+    }
+
+    /**
+     * Emitted once the editor comes into focus.
+     * @event focus
+     *
+     *
+     **/
+    onFocus(e) {
+        if (this.$isFocused)
+            return;
+        this.$isFocused = true;
+        this.renderer.showCursor();
+        this.renderer.visualizeFocus();
+        this._emit("focus", e);
+    }
+
+    /**
+     * Emitted once the editor has been blurred.
+     * @event blur
+     *
+     *
+     **/
+    onBlur(e) {
+        if (!this.$isFocused)
+            return;
+        this.$isFocused = false;
+        this.renderer.hideCursor();
+        this.renderer.visualizeBlur();
+        this._emit("blur", e);
+    }
+
+    $cursorChange() {
+        this.renderer.updateCursor();
+        this.$highlightBrackets();
+        this.$updateHighlightActiveLine();
+    }
+
+    /**
+     * Emitted whenever the document is changed.
+     * @event change
+     * @param {Object} delta Contains a single property, `data`, which has the delta of changes
+     *
+     *
+     *
+     **/
+    onDocumentChange(delta) {
+        // Rerender and emit "change" event.
+        var wrap = this.session.$useWrapMode;
+        var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);
+        this.renderer.updateLines(delta.start.row, lastRow, wrap);
+
+        this._signal("change", delta);
+        
+        // Update cursor because tab characters can influence the cursor position.
+        this.$cursorChange();
+    }
+
+    onTokenizerUpdate(e) {
+        var rows = e.data;
+        this.renderer.updateLines(rows.first, rows.last);
+    }
+
+
+    onScrollTopChange() {
+        this.renderer.scrollToY(this.session.getScrollTop());
+    }
+
+    onScrollLeftChange() {
+        this.renderer.scrollToX(this.session.getScrollLeft());
+    }
+
+    /**
+     * Emitted when the selection changes.
+     *
+     **/
+    onCursorChange() {
+        this.$cursorChange();
+        this._signal("changeSelection");
+    }
+
+    $updateHighlightActiveLine() {
+        var session = this.getSession();
+
+        var highlight;
+        if (this.$highlightActiveLine) {
+            if (this.$selectionStyle != "line" || !this.selection.isMultiLine())
+                highlight = this.getCursorPosition();
+            if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty())
+                highlight = false;
+            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))
+                highlight = false;
+        }
+
+        if (session.$highlightLineMarker && !highlight) {
+            session.removeMarker(session.$highlightLineMarker.id);
+            session.$highlightLineMarker = null;
+        } else if (!session.$highlightLineMarker && highlight) {
+            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
+            range.id = session.addMarker(range, "ace_active-line", "screenLine");
+            session.$highlightLineMarker = range;
+        } else if (highlight) {
+            session.$highlightLineMarker.start.row = highlight.row;
+            session.$highlightLineMarker.end.row = highlight.row;
+            session.$highlightLineMarker.start.column = highlight.column;
+            session._signal("changeBackMarker");
+        }
+    }
+
+    onSelectionChange(e) {
+        var session = this.session;
+
+        if (session.$selectionMarker) {
+            session.removeMarker(session.$selectionMarker);
+        }
+        session.$selectionMarker = null;
+
+        if (!this.selection.isEmpty()) {
+            var range = this.selection.getRange();
+            var style = this.getSelectionStyle();
+            session.$selectionMarker = session.addMarker(range, "ace_selection", style);
+        } else {
+            this.$updateHighlightActiveLine();
+        }
+
+        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();
+        this.session.highlight(re);
+
+        this._signal("changeSelection");
+    }
+
+    $getSelectionHighLightRegexp() {
+        var session = this.session;
+
+        var selection = this.getSelectionRange();
+        if (selection.isEmpty() || selection.isMultiLine())
+            return;
+
+        var startColumn = selection.start.column;
+        var endColumn = selection.end.column;
+        var line = session.getLine(selection.start.row);
+        
+        var needle = line.substring(startColumn, endColumn);
+        // maximum allowed size for regular expressions in 32000, 
+        // but getting close to it has significant impact on the performance
+        if (needle.length > 5000 || !/[\w\d]/.test(needle))
+            return;
+
+        var re = this.$search.$assembleRegExp({
+            wholeWord: true,
+            caseSensitive: true,
+            needle: needle
+        });
+        
+        var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1);
+        if (!re.test(wordWithBoundary))
+            return;
+        
+        return re;
+    }
+
+
+    onChangeFrontMarker() {
+        this.renderer.updateFrontMarkers();
+    }
+
+    onChangeBackMarker() {
+        this.renderer.updateBackMarkers();
+    }
+
+
+    onChangeBreakpoint() {
+        this.renderer.updateBreakpoints();
+    }
+
+    onChangeAnnotation() {
+        this.renderer.setAnnotations(this.session.getAnnotations());
+    }
+
+
+    onChangeMode (e) {
+        this.renderer.updateText();
+        this._emit("changeMode", e);
+    }
+
+
+    onChangeWrapLimit() {
+        this.renderer.updateFull();
+    }
+
+    onChangeWrapMode() {
+        this.renderer.onResize(true);
+    }
+
+
+    onChangeFold() {
+        // Update the active line marker as due to folding changes the current
+        // line range on the screen might have changed.
+        this.$updateHighlightActiveLine();
+        // TODO: This might be too much updating. Okay for now.
+        this.renderer.updateFull();
+    }
+
+    
+    /**
+     * Returns the string of text currently highlighted.
+     * @returns {String}
+     **/
+    getSelectedText() {
+        return this.session.getTextRange(this.getSelectionRange());
+    }
+    
+    /**
+     * Emitted when text is copied.
+     * @event copy
+     * @param {String} text The copied text
+     *
+     **/
+    /**
+     * Returns the string of text currently highlighted.
+     * @returns {String}
+     **/
+    getCopyText () {
+        var text = this.getSelectedText();
+        var nl = this.session.doc.getNewLineCharacter();
+        var copyLine= false;
+        if (!text && this.$copyWithEmptySelection) {
+            copyLine = true;
+            var ranges = this.selection.getAllRanges();
+            for (var i = 0; i < ranges.length; i++) {
+                var range = ranges[i];
+                if (i && ranges[i - 1].start.row == range.start.row)
+                    continue;
+                text += this.session.getLine(range.start.row) + nl;
+            }
+        }
+        var e = {text: text};
+        this._signal("copy", e);
+        clipboard.lineMode = copyLine ? e.text : false;
+        return e.text;
+    }
+
+    /**
+     * Called whenever a text "copy" happens.
+     **/
+    onCopy() {
+        this.commands.exec("copy", this);
+    }
+
+    /**
+     * Called whenever a text "cut" happens.
+     **/
+    onCut() {
+        this.commands.exec("cut", this);
+    }
+
+    /**
+     * Emitted when text is pasted.
+     * @event paste
+     * @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.
+     *
+     *
+     **/
+    /**
+     * Called whenever a text "paste" happens.
+     * @param {String} text The pasted text
+     *
+     *
+     **/
+    onPaste(text, event) {
+        var e = {text: text, event: event};
+        this.commands.exec("paste", this, e);
+    }
+    
+    $handlePaste(e) {
+        if (typeof e == "string") 
+            e = {text: e};
+        this._signal("paste", e);
+        var text = e.text;
+
+        var lineMode = text === clipboard.lineMode;
+        var session = this.session;
+        if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {
+            if (lineMode)
+                session.insert({ row: this.selection.lead.row, column: 0 }, text);
+            else
+                this.insert(text);
+        } else if (lineMode) {
+            this.selection.rangeList.ranges.forEach(function(range) {
+                session.insert({ row: range.start.row, column: 0 }, text);
+            });
+        } else {
+            var lines = text.split(/\r\n|\r|\n/);
+            var ranges = this.selection.rangeList.ranges;
+    
+            var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]);
+            if (lines.length != ranges.length || isFullLine)
+                return this.commands.exec("insertstring", this, text);
+    
+            for (var i = ranges.length; i--;) {
+                var range = ranges[i];
+                if (!range.isEmpty())
+                    session.remove(range);
+    
+                session.insert(range.start, lines[i]);
+            }
+        }
+    }
+
+    execCommand(command, args) {
+        return this.commands.exec(command, this, args);
+    }
+
+    /**
+     * Inserts `text` into wherever the cursor is pointing.
+     * @param {String} text The new text to add
+     *
+     **/
+    insert(text, pasted) {
+        var session = this.session;
+        var mode = session.getMode();
+        var cursor = this.getCursorPosition();
+
+        if (this.getBehavioursEnabled() && !pasted) {
+            // Get a transform if the current mode wants one.
+            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
+            if (transform) {
+                if (text !== transform.text) {
+                    // keep automatic insertion in a separate delta, unless it is in multiselect mode
+                    if (!this.inVirtualSelectionMode) {
+                        this.session.mergeUndoDeltas = false;
+                        this.mergeNextCommand = false;
+                    }
+                }
+                text = transform.text;
+
+            }
+        }
+        
+        if (text == "\t")
+            text = this.session.getTabString();
+
+        // remove selected text
+        if (!this.selection.isEmpty()) {
+            var range = this.getSelectionRange();
+            cursor = this.session.remove(range);
+            this.clearSelection();
+        }
+        else if (this.session.getOverwrite() && text.indexOf("\n") == -1) {
+            var range = new Range.fromPoints(cursor, cursor);
+            range.end.column += text.length;
+            this.session.remove(range);
+        }
+
+        if (text == "\n" || text == "\r\n") {
+            var line = session.getLine(cursor.row);
+            if (cursor.column > line.search(/\S|$/)) {
+                var d = line.substr(cursor.column).search(/\S|$/);
+                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);
+            }
+        }
+        this.clearSelection();
+
+        var start = cursor.column;
+        var lineState = session.getState(cursor.row);
+        var line = session.getLine(cursor.row);
+        var shouldOutdent = mode.checkOutdent(lineState, line, text);
+        session.insert(cursor, text);
+
+        if (transform && transform.selection) {
+            if (transform.selection.length == 2) { // Transform relative to the current column
+                this.selection.setSelectionRange(
+                    new Range(cursor.row, start + transform.selection[0],
+                              cursor.row, start + transform.selection[1]));
+            } else { // Transform relative to the current row.
+                this.selection.setSelectionRange(
+                    new Range(cursor.row + transform.selection[0],
+                              transform.selection[1],
+                              cursor.row + transform.selection[2],
+                              transform.selection[3]));
+            }
+        }
+        if (this.$enableAutoIndent) {
+            if (session.getDocument().isNewLine(text)) {
+                var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
+
+                session.insert({row: cursor.row+1, column: 0}, lineIndent);
+            }
+            if (shouldOutdent)
+                mode.autoOutdent(lineState, session, cursor.row);
+        }
+    }
+
+    autoIndent() {
+        var session = this.session;
+        var mode = session.getMode();
+
+        var startRow, endRow;
+        if (this.selection.isEmpty()) {
+            startRow = 0;
+            endRow = session.doc.getLength() - 1;
+        } else {
+            var selectedRange = this.getSelectionRange();
+
+            startRow = selectedRange.start.row;
+            endRow = selectedRange.end.row;
+        }
+
+        var prevLineState = "";
+        var prevLine = "";
+        var lineIndent = "";
+        var line, currIndent, range;
+        var tab = session.getTabString();
+
+        for (var row = startRow; row <= endRow; row++) {
+            if (row > 0) {
+                prevLineState = session.getState(row - 1);
+                prevLine = session.getLine(row - 1);
+                lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab);
+            }
+
+            line = session.getLine(row);
+            currIndent = mode.$getIndent(line);
+            if (lineIndent !== currIndent) {
+                if (currIndent.length > 0) {
+                    range = new Range(row, 0, row, currIndent.length);
+                    session.remove(range);
+                }
+                if (lineIndent.length > 0) {
+                    session.insert({row: row, column: 0}, lineIndent);
+                }
+            }
+
+            mode.autoOutdent(prevLineState, session, row);
+        }
+    }
+
+
+    onTextInput(text, composition) {
+        if (!composition)
+            return this.keyBinding.onTextInput(text);
+        
+        this.startOperation({command: { name: "insertstring" }});
+        var applyComposition = this.applyComposition.bind(this, text, composition);
+        if (this.selection.rangeCount)
+            this.forEachSelection(applyComposition);
+        else
+            applyComposition();
+        this.endOperation();
+    }
+    
+    applyComposition(text, composition) {
+        if (composition.extendLeft || composition.extendRight) {
+            var r = this.selection.getRange();
+            r.start.column -= composition.extendLeft;
+            r.end.column += composition.extendRight;
+            if (r.start.column < 0) {
+                r.start.row--;
+                r.start.column += this.session.getLine(r.start.row).length + 1;
+            }
+            this.selection.setRange(r);
+            if (!text && !r.isEmpty())
+                this.remove();
+        }
+        if (text || !this.selection.isEmpty())
+            this.insert(text, true);
+        if (composition.restoreStart || composition.restoreEnd) {
+            var r = this.selection.getRange();
+            r.start.column -= composition.restoreStart;
+            r.end.column -= composition.restoreEnd;
+            this.selection.setRange(r);
+        }
+    }
+
+    onCommandKey(e, hashId, keyCode) {
+        return this.keyBinding.onCommandKey(e, hashId, keyCode);
+    }
+
+    /**
+     * 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.
+     * @param {Boolean} overwrite Defines whether or not to set overwrites
+     *
+     *
+     * @related EditSession.setOverwrite
+     **/
+    setOverwrite(overwrite) {
+        this.session.setOverwrite(overwrite);
+    }
+
+    /**
+     * Returns `true` if overwrites are enabled; `false` otherwise.
+     * @returns {Boolean}
+     * @related EditSession.getOverwrite
+     **/
+    getOverwrite() {
+        return this.session.getOverwrite();
+    }
+
+    /**
+     * Sets the value of overwrite to the opposite of whatever it currently is.
+     * @related EditSession.toggleOverwrite
+     **/
+    toggleOverwrite() {
+        this.session.toggleOverwrite();
+    }
+
+    /**
+     * Sets how fast the mouse scrolling should do.
+     * @param {Number} speed A value indicating the new speed (in milliseconds)
+     **/
+    setScrollSpeed(speed) {
+        this.setOption("scrollSpeed", speed);
+    }
+
+    /**
+     * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).
+     * @returns {Number}
+     **/
+    getScrollSpeed() {
+        return this.getOption("scrollSpeed");
+    }
+
+    /**
+     * Sets the delay (in milliseconds) of the mouse drag.
+     * @param {Number} dragDelay A value indicating the new delay
+     **/
+    setDragDelay(dragDelay) {
+        this.setOption("dragDelay", dragDelay);
+    }
+
+    /**
+     * Returns the current mouse drag delay.
+     * @returns {Number}
+     **/
+    getDragDelay() {
+        return this.getOption("dragDelay");
+    }
+
+    /**
+     * Emitted when the selection style changes, via [[Editor.setSelectionStyle]].
+     * @event changeSelectionStyle
+     * @param {Object} data Contains one property, `data`, which indicates the new selection style
+     **/
+    /**
+     * Draw selection markers spanning whole line, or only over selected text. Default value is "line"
+     * @param {String} val The new selection style "line"|"text"
+     *
+     **/
+    setSelectionStyle(val) {
+        this.setOption("selectionStyle", val);
+    }
+
+    /**
+     * Returns the current selection style.
+     * @returns {String}
+     **/
+    getSelectionStyle() {
+        return this.getOption("selectionStyle");
+    }
+
+    /**
+     * Determines whether or not the current line should be highlighted.
+     * @param {Boolean} shouldHighlight Set to `true` to highlight the current line
+     **/
+    setHighlightActiveLine(shouldHighlight) {
+        this.setOption("highlightActiveLine", shouldHighlight);
+    }
+    /**
+     * Returns `true` if current lines are always highlighted.
+     * @return {Boolean}
+     **/
+    getHighlightActiveLine() {
+        return this.getOption("highlightActiveLine");
+    }
+    setHighlightGutterLine(shouldHighlight) {
+        this.setOption("highlightGutterLine", shouldHighlight);
+    }
+
+    getHighlightGutterLine() {
+        return this.getOption("highlightGutterLine");
+    }
+
+    /**
+     * Determines if the currently selected word should be highlighted.
+     * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word
+     *
+     **/
+    setHighlightSelectedWord(shouldHighlight) {
+        this.setOption("highlightSelectedWord", shouldHighlight);
+    }
+
+    /**
+     * Returns `true` if currently highlighted words are to be highlighted.
+     * @returns {Boolean}
+     **/
+    getHighlightSelectedWord() {
+        return this.$highlightSelectedWord;
+    }
+
+    setAnimatedScroll(shouldAnimate){
+        this.renderer.setAnimatedScroll(shouldAnimate);
+    }
+
+    getAnimatedScroll(){
+        return this.renderer.getAnimatedScroll();
+    }
+
+    /**
+     * If `showInvisibles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor.
+     * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters
+     *
+     **/
+    setShowInvisibles(showInvisibles) {
+        this.renderer.setShowInvisibles(showInvisibles);
+    }
+
+    /**
+     * Returns `true` if invisible characters are being shown.
+     * @returns {Boolean}
+     **/
+    getShowInvisibles() {
+        return this.renderer.getShowInvisibles();
+    }
+
+    setDisplayIndentGuides(display) {
+        this.renderer.setDisplayIndentGuides(display);
+    }
+
+    getDisplayIndentGuides() {
+        return this.renderer.getDisplayIndentGuides();
+    }
+
+    setHighlightIndentGuides(highlight) {
+        this.renderer.setHighlightIndentGuides(highlight);
+    }
+
+    getHighlightIndentGuides() {
+        return this.renderer.getHighlightIndentGuides();
+    }
+
+    /**
+     * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.
+     * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin
+     *
+     **/
+    setShowPrintMargin(showPrintMargin) {
+        this.renderer.setShowPrintMargin(showPrintMargin);
+    }
+
+    /**
+     * Returns `true` if the print margin is being shown.
+     * @returns {Boolean}
+     **/
+    getShowPrintMargin() {
+        return this.renderer.getShowPrintMargin();
+    }
+
+    /**
+     * Sets the column defining where the print margin should be.
+     * @param {Number} showPrintMargin Specifies the new print margin
+     *
+     **/
+    setPrintMarginColumn(showPrintMargin) {
+        this.renderer.setPrintMarginColumn(showPrintMargin);
+    }
+
+    /**
+     * Returns the column number of where the print margin is.
+     * @returns {Number}
+     **/
+    getPrintMarginColumn() {
+        return this.renderer.getPrintMarginColumn();
+    }
+
+    /**
+     * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.
+     * @param {Boolean} readOnly Specifies whether the editor can be modified or not
+     *
+     **/
+    setReadOnly(readOnly) {
+        this.setOption("readOnly", readOnly);
+    }
+
+    /**
+     * Returns `true` if the editor is set to read-only mode.
+     * @returns {Boolean}
+     **/
+    getReadOnly() {
+        return this.getOption("readOnly");
+    }
+
+    /**
+     * 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}
+     * @param {Boolean} enabled Enables or disables behaviors
+     *
+     **/
+    setBehavioursEnabled(enabled) {
+        this.setOption("behavioursEnabled", enabled);
+    }
+
+    /**
+     * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}
+     *
+     * @returns {Boolean}
+     **/
+    getBehavioursEnabled() {
+        return this.getOption("behavioursEnabled");
+    }
+
+    /**
+     * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets
+     * when such a character is typed in.
+     * @param {Boolean} enabled Enables or disables wrapping behaviors
+     *
+     **/
+    setWrapBehavioursEnabled(enabled) {
+        this.setOption("wrapBehavioursEnabled", enabled);
+    }
+
+    /**
+     * Returns `true` if the wrapping behaviors are currently enabled.
+     **/
+    getWrapBehavioursEnabled() {
+        return this.getOption("wrapBehavioursEnabled");
+    }
+
+    /**
+     * Indicates whether the fold widgets should be shown or not.
+     * @param {Boolean} show Specifies whether the fold widgets are shown
+     **/
+    setShowFoldWidgets(show) {
+        this.setOption("showFoldWidgets", show);
+
+    }
+    /**
+     * Returns `true` if the fold widgets are shown.
+     * @return {Boolean}
+     **/
+    getShowFoldWidgets() {
+        return this.getOption("showFoldWidgets");
+    }
+
+    setFadeFoldWidgets(fade) {
+        this.setOption("fadeFoldWidgets", fade);
+    }
+
+    getFadeFoldWidgets() {
+        return this.getOption("fadeFoldWidgets");
+    }
+
+    /**
+     * Removes the current selection or one character.
+     * @param {String} dir The direction of the deletion to occur, either "left" or "right"
+     *
+     **/
+    remove(dir) {
+        if (this.selection.isEmpty()){
+            if (dir == "left")
+                this.selection.selectLeft();
+            else
+                this.selection.selectRight();
+        }
+
+        var range = this.getSelectionRange();
+        if (this.getBehavioursEnabled()) {
+            var session = this.session;
+            var state = session.getState(range.start.row);
+            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
+
+            if (range.end.column === 0) {
+                var text = session.getTextRange(range);
+                if (text[text.length - 1] == "\n") {
+                    var line = session.getLine(range.end.row);
+                    if (/^\s+$/.test(line)) {
+                        range.end.column = line.length;
+                    }
+                }
+            }
+            if (new_range)
+                range = new_range;
+        }
+
+        this.session.remove(range);
+        this.clearSelection();
+    }
+
+    /**
+     * Removes the word directly to the right of the current selection.
+     **/
+    removeWordRight() {
+        if (this.selection.isEmpty())
+            this.selection.selectWordRight();
+
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    }
+
+    /**
+     * Removes the word directly to the left of the current selection.
+     **/
+    removeWordLeft() {
+        if (this.selection.isEmpty())
+            this.selection.selectWordLeft();
+
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    }
+
+    /**
+     * Removes all the words to the left of the current selection, until the start of the line.
+     **/
+    removeToLineStart() {
+        if (this.selection.isEmpty())
+            this.selection.selectLineStart();
+        if (this.selection.isEmpty())
+            this.selection.selectLeft();
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    }
+
+    /**
+     * Removes all the words to the right of the current selection, until the end of the line.
+     **/
+    removeToLineEnd() {
+        if (this.selection.isEmpty())
+            this.selection.selectLineEnd();
+
+        var range = this.getSelectionRange();
+        if (range.start.column == range.end.column && range.start.row == range.end.row) {
+            range.end.column = 0;
+            range.end.row++;
+        }
+
+        this.session.remove(range);
+        this.clearSelection();
+    }
+
+    /**
+     * Splits the line at the current selection (by inserting an `'\n'`).
+     **/
+    splitLine() {
+        if (!this.selection.isEmpty()) {
+            this.session.remove(this.getSelectionRange());
+            this.clearSelection();
+        }
+
+        var cursor = this.getCursorPosition();
+        this.insert("\n");
+        this.moveCursorToPosition(cursor);
+    }
+
+    /**
+     * Set the "ghost" text in provided position. "Ghost" text is a kind of
+     * preview text inside the editor which can be used to preview some code
+     * inline in the editor such as, for example, code completions.
+     * 
+     * @param {String} text Text to be inserted as "ghost" text
+     * @param {object} position Position to insert text to
+     */
+    setGhostText(text, position) {
+        if (!this.session.widgetManager) {
+            this.session.widgetManager = new LineWidgets(this.session);
+            this.session.widgetManager.attach(this);
+        }
+        this.renderer.setGhostText(text, position);
+    }
+
+    /**
+     * Removes "ghost" text currently displayed in the editor.
+     */
+    removeGhostText() {
+        if (!this.session.widgetManager) return;
+
+        this.renderer.removeGhostText();
+    }
+
+    /**
+     * Transposes current line.
+     **/
+    transposeLetters() {
+        if (!this.selection.isEmpty()) {
+            return;
+        }
+
+        var cursor = this.getCursorPosition();
+        var column = cursor.column;
+        if (column === 0)
+            return;
+
+        var line = this.session.getLine(cursor.row);
+        var swap, range;
+        if (column < line.length) {
+            swap = line.charAt(column) + line.charAt(column-1);
+            range = new Range(cursor.row, column-1, cursor.row, column+1);
+        }
+        else {
+            swap = line.charAt(column-1) + line.charAt(column-2);
+            range = new Range(cursor.row, column-2, cursor.row, column);
+        }
+        this.session.replace(range, swap);
+        this.session.selection.moveToPosition(range.end);
+    }
+
+    /**
+     * Converts the current selection entirely into lowercase.
+     **/
+    toLowerCase() {
+        var originalRange = this.getSelectionRange();
+        if (this.selection.isEmpty()) {
+            this.selection.selectWord();
+        }
+
+        var range = this.getSelectionRange();
+        var text = this.session.getTextRange(range);
+        this.session.replace(range, text.toLowerCase());
+        this.selection.setSelectionRange(originalRange);
+    }
+
+    /**
+     * Converts the current selection entirely into uppercase.
+     **/
+    toUpperCase() {
+        var originalRange = this.getSelectionRange();
+        if (this.selection.isEmpty()) {
+            this.selection.selectWord();
+        }
+
+        var range = this.getSelectionRange();
+        var text = this.session.getTextRange(range);
+        this.session.replace(range, text.toUpperCase());
+        this.selection.setSelectionRange(originalRange);
+    }
+
+    /**
+     * Inserts an indentation into the current cursor position or indents the selected lines.
+     *
+     * @related EditSession.indentRows
+     **/
+    indent() {
+        var session = this.session;
+        var range = this.getSelectionRange();
+
+        if (range.start.row < range.end.row) {
+            var rows = this.$getSelectedRows();
+            session.indentRows(rows.first, rows.last, "\t");
+            return;
+        } else if (range.start.column < range.end.column) {
+            var text = session.getTextRange(range);
+            if (!/^\s+$/.test(text)) {
+                var rows = this.$getSelectedRows();
+                session.indentRows(rows.first, rows.last, "\t");
+                return;
+            }
+        }
+        
+        var line = session.getLine(range.start.row);
+        var position = range.start;
+        var size = session.getTabSize();
+        var column = session.documentToScreenColumn(position.row, position.column);
+
+        if (this.session.getUseSoftTabs()) {
+            var count = (size - column % size);
+            var indentString = lang.stringRepeat(" ", count);
+        } else {
+            var count = column % size;
+            while (line[range.start.column - 1] == " " && count) {
+                range.start.column--;
+                count--;
+            }
+            this.selection.setSelectionRange(range);
+            indentString = "\t";
+        }
+        return this.insert(indentString);
+    }
+
+    /**
+     * Indents the current line.
+     * @related EditSession.indentRows
+     **/
+    blockIndent() {
+        var rows = this.$getSelectedRows();
+        this.session.indentRows(rows.first, rows.last, "\t");
+    }
+
+    /**
+     * Outdents the current line.
+     * @related EditSession.outdentRows
+     **/
+    blockOutdent() {
+        var selection = this.session.getSelection();
+        this.session.outdentRows(selection.getRange());
+    }
+
+    // TODO: move out of core when we have good mechanism for managing extensions
+    sortLines() {
+        var rows = this.$getSelectedRows();
+        var session = this.session;
+
+        var lines = [];
+        for (var i = rows.first; i <= rows.last; i++)
+            lines.push(session.getLine(i));
+
+        lines.sort(function(a, b) {
+            if (a.toLowerCase() < b.toLowerCase()) return -1;
+            if (a.toLowerCase() > b.toLowerCase()) return 1;
+            return 0;
+        });
+
+        var deleteRange = new Range(0, 0, 0, 0);
+        for (var i = rows.first; i <= rows.last; i++) {
+            var line = session.getLine(i);
+            deleteRange.start.row = i;
+            deleteRange.end.row = i;
+            deleteRange.end.column = line.length;
+            session.replace(deleteRange, lines[i-rows.first]);
+        }
+    }
+
+    /**
+     * Given the currently selected range, this function either comments all the lines, or uncomments all of them.
+     **/
+    toggleCommentLines() {
+        var state = this.session.getState(this.getCursorPosition().row);
+        var rows = this.$getSelectedRows();
+        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
+    }
+
+    toggleBlockComment() {
+        var cursor = this.getCursorPosition();
+        var state = this.session.getState(cursor.row);
+        var range = this.getSelectionRange();
+        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);
+    }
+
+    /**
+     * Works like [[EditSession.getTokenAt]], except it returns a number.
+     * @returns {Number}
+     **/
+    getNumberAt(row, column) {
+        var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g;
+        _numberRx.lastIndex = 0;
+
+        var s = this.session.getLine(row);
+        while (_numberRx.lastIndex < column) {
+            var m = _numberRx.exec(s);
+            if(m.index <= column && m.index+m[0].length >= column){
+                var number = {
+                    value: m[0],
+                    start: m.index,
+                    end: m.index+m[0].length
+                };
+                return number;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * If the character before the cursor is a number, this functions changes its value by `amount`.
+     * @param {Number} amount The value to change the numeral by (can be negative to decrease value)
+     *
+     **/
+    modifyNumber(amount) {
+        var row = this.selection.getCursor().row;
+        var column = this.selection.getCursor().column;
+
+        // get the char before the cursor
+        var charRange = new Range(row, column-1, row, column);
+
+        var c = this.session.getTextRange(charRange);
+        // if the char is a digit
+        if (!isNaN(parseFloat(c)) && isFinite(c)) {
+            // get the whole number the digit is part of
+            var nr = this.getNumberAt(row, column);
+            // if number found
+            if (nr) {
+                var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
+                var decimals = nr.start + nr.value.length - fp;
+
+                var t = parseFloat(nr.value);
+                t *= Math.pow(10, decimals);
+
+
+                if(fp !== nr.end && column < fp){
+                    amount *= Math.pow(10, nr.end - column - 1);
+                } else {
+                    amount *= Math.pow(10, nr.end - column);
+                }
+
+                t += amount;
+                t /= Math.pow(10, decimals);
+                var nnr = t.toFixed(decimals);
+
+                //update number
+                var replaceRange = new Range(row, nr.start, row, nr.end);
+                this.session.replace(replaceRange, nnr);
+
+                //reposition the cursor
+                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
+
+            }
+        } else {
+            this.toggleWord();
+        }
+    }
+    
+    toggleWord() {
+        var row = this.selection.getCursor().row;
+        var column = this.selection.getCursor().column;
+        this.selection.selectWord();
+        var currentState = this.getSelectedText();
+        var currWordStart = this.selection.getWordRange().start.column;
+        var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\s/);
+        var delta = column - currWordStart - 1;
+        if (delta < 0) delta = 0;
+        var curLength = 0, itLength = 0;
+        var that = this;
+        if (currentState.match(/[A-Za-z0-9_]+/)) {
+            wordParts.forEach(function (item, i) {
+                itLength = curLength + item.length;
+                if (delta >= curLength && delta <= itLength) {
+                    currentState = item;
+                    that.selection.clearSelection();
+                    that.moveCursorTo(row, curLength + currWordStart);
+                    that.selection.selectTo(row, itLength + currWordStart);
+                }
+                curLength = itLength;
+            });
+        }
+
+        var wordPairs = this.$toggleWordPairs;
+        var reg;
+        for (var i = 0; i < wordPairs.length; i++) {
+            var item = wordPairs[i];
+            for (var j = 0; j <= 1; j++) {
+                var negate = +!j;
+                var firstCondition = currentState.match(new RegExp('^\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\s?$', 'i'));
+                if (firstCondition) {
+                    var secondCondition = currentState.match(new RegExp('([_]|^|\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\s)', 'g'));
+                    if (secondCondition) {
+                        reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) {
+                            var res = item[negate];
+                            if (result.toUpperCase() == result) {
+                                res = res.toUpperCase();
+                            } else if (result.charAt(0).toUpperCase() == result.charAt(0)) {
+                                res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1);
+                            }
+                            return res;
+                        });
+                        this.insert(reg);
+                        reg = "";
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Finds link at defined {row} and {column}
+     * @returns {String}
+     **/
+    findLinkAt(row, column) {
+        var line = this.session.getLine(row);
+        var wordParts = line.split(/((?:https?|ftp):\/\/[\S]+)/);
+        var columnPosition = column;
+        if (columnPosition < 0) columnPosition = 0;
+        var previousPosition = 0, currentPosition = 0, match;
+        for (let item of wordParts) {
+            currentPosition = previousPosition + item.length;
+            if (columnPosition >= previousPosition && columnPosition <= currentPosition) {
+                if (item.match(/((?:https?|ftp):\/\/[\S]+)/)) {
+                    match = item.replace(/[\s:.,'";}\]]+$/, "");
+                    break;
+                }
+            }
+            previousPosition = currentPosition;
+        }
+        return match;
+    }
+
+    /**
+     * Open valid url under cursor in another tab
+     * @returns {Boolean}
+     **/
+    openLink() {
+        var cursor =  this.selection.getCursor();
+        var url = this.findLinkAt(cursor.row, cursor.column);
+        if (url)
+            window.open(url, '_blank');
+        return url != null;
+    }
+
+    /**
+     * Removes all the lines in the current selection
+     * @related EditSession.remove
+     **/
+    removeLines() {
+        var rows = this.$getSelectedRows();
+        this.session.removeFullLines(rows.first, rows.last);
+        this.clearSelection();
+    }
+
+    duplicateSelection() {
+        var sel = this.selection;
+        var doc = this.session;
+        var range = sel.getRange();
+        var reverse = sel.isBackwards();
+        if (range.isEmpty()) {
+            var row = range.start.row;
+            doc.duplicateLines(row, row);
+        } else {
+            var point = reverse ? range.start : range.end;
+            var endPoint = doc.insert(point, doc.getTextRange(range), false);
+            range.start = point;
+            range.end = endPoint;
+
+            sel.setSelectionRange(range, reverse);
+        }
+    }
+
+    /**
+     * Shifts all the selected lines down one row.
+     *
+     * @returns {Number} On success, it returns -1.
+     * @related EditSession.moveLinesUp
+     **/
+    moveLinesDown() {
+        this.$moveLines(1, false);
+    }
+
+    /**
+     * Shifts all the selected lines up one row.
+     * @returns {Number} On success, it returns -1.
+     * @related EditSession.moveLinesDown
+     **/
+    moveLinesUp() {
+        this.$moveLines(-1, false);
+    }
+
+    /**
+     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:
+     * ```json
+     *    { row: newRowLocation, column: newColumnLocation }
+     * ```
+     * @param {Range} range The range of text you want moved within the document
+     * @param {Object} toPosition The location (row and column) where you want to move the text to
+     *
+     * @returns {Range} The new range where the text was moved to.
+     * @related EditSession.moveText
+     **/
+    moveText(range, toPosition, copy) {
+        return this.session.moveText(range, toPosition, copy);
+    }
+
+    /**
+     * Copies all the selected lines up one row.
+     * @returns {Number} On success, returns 0.
+     *
+     **/
+   copyLinesUp() {
+        this.$moveLines(-1, true);
+    }
+
+    /**
+     * Copies all the selected lines down one row.
+     * @returns {Number} On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`.
+     * @related EditSession.duplicateLines
+     *
+     **/
+    copyLinesDown() {
+        this.$moveLines(1, true);
+    }
+
+    /**
+     * for internal use
+     * @ignore
+     *
+     **/
+    $moveLines(dir, copy) {
+        var rows, moved;
+        var selection = this.selection;
+        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
+            var range = selection.toOrientedRange();
+            rows = this.$getSelectedRows(range);
+            moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);
+            if (copy && dir == -1) moved = 0;
+            range.moveBy(moved, 0);
+            selection.fromOrientedRange(range);
+        } else {
+            var ranges = selection.rangeList.ranges;
+            selection.rangeList.detach(this.session);
+            this.inVirtualSelectionMode = true;
+            
+            var diff = 0;
+            var totalDiff = 0;
+            var l = ranges.length;
+            for (var i = 0; i < l; i++) {
+                var rangeIndex = i;
+                ranges[i].moveBy(diff, 0);
+                rows = this.$getSelectedRows(ranges[i]);
+                var first = rows.first;
+                var last = rows.last;
+                while (++i < l) {
+                    if (totalDiff) ranges[i].moveBy(totalDiff, 0);
+                    var subRows = this.$getSelectedRows(ranges[i]);
+                    if (copy && subRows.first != last)
+                        break;
+                    else if (!copy && subRows.first > last + 1)
+                        break;
+                    last = subRows.last;
+                }
+                i--;
+                diff = this.session.$moveLines(first, last, copy ? 0 : dir);
+                if (copy && dir == -1) rangeIndex = i + 1;
+                while (rangeIndex <= i) {
+                    ranges[rangeIndex].moveBy(diff, 0);
+                    rangeIndex++;
+                }
+                if (!copy) diff = 0;
+                totalDiff += diff;
+            }
+            
+            selection.fromOrientedRange(selection.ranges[0]);
+            selection.rangeList.attach(this.session);
+            this.inVirtualSelectionMode = false;
+        }
+    }
+
+    /**
+     * Returns an object indicating the currently selected rows. The object looks like this:
+     *
+     * ```json
+     * { first: range.start.row, last: range.end.row }
+     * ```
+     *
+     * @returns {Object}
+     **/
+    $getSelectedRows(range) {
+        range = (range || this.getSelectionRange()).collapseRows();
+
+        return {
+            first: this.session.getRowFoldStart(range.start.row),
+            last: this.session.getRowFoldEnd(range.end.row)
+        };
+    }
+
+    onCompositionStart(compositionState) {
+        this.renderer.showComposition(compositionState);
+    }
+
+    onCompositionUpdate(text) {
+        this.renderer.setCompositionText(text);
+    }
+
+    onCompositionEnd() {
+        this.renderer.hideComposition();
+    }
+
+    /**
+     * {:VirtualRenderer.getFirstVisibleRow}
+     *
+     * @returns {Number}
+     * @related VirtualRenderer.getFirstVisibleRow
+     **/
+    getFirstVisibleRow() {
+        return this.renderer.getFirstVisibleRow();
+    }
+
+    /**
+     * {:VirtualRenderer.getLastVisibleRow}
+     *
+     * @returns {Number}
+     * @related VirtualRenderer.getLastVisibleRow
+     **/
+    getLastVisibleRow() {
+        return this.renderer.getLastVisibleRow();
+    }
+
+    /**
+     * Indicates if the row is currently visible on the screen.
+     * @param {Number} row The row to check
+     *
+     * @returns {Boolean}
+     **/
+    isRowVisible(row) {
+        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
+    }
+
+    /**
+     * Indicates if the entire row is currently visible on the screen.
+     * @param {Number} row The row to check
+     *
+     *
+     * @returns {Boolean}
+     **/
+    isRowFullyVisible(row) {
+        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
+    }
+
+    /**
+     * Returns the number of currently visible rows.
+     * @returns {Number}
+     **/
+    $getVisibleRowCount() {
+        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
+    }
+
+    $moveByPage(dir, select) {
+        var renderer = this.renderer;
+        var config = this.renderer.layerConfig;
+        var rows = dir * Math.floor(config.height / config.lineHeight);
+
+        if (select === true) {
+            this.selection.$moveSelection(function(){
+                this.moveCursorBy(rows, 0);
+            });
+        } else if (select === false) {
+            this.selection.moveCursorBy(rows, 0);
+            this.selection.clearSelection();
+        }
+
+        var scrollTop = renderer.scrollTop;
+
+        renderer.scrollBy(0, rows * config.lineHeight);
+        if (select != null)
+            renderer.scrollCursorIntoView(null, 0.5);
+
+        renderer.animateScrolling(scrollTop);
+    }
+
+    /**
+     * Selects the text from the current position of the document until where a "page down" finishes.
+     **/
+    selectPageDown() {
+        this.$moveByPage(1, true);
+    }
+
+    /**
+     * Selects the text from the current position of the document until where a "page up" finishes.
+     **/
+    selectPageUp() {
+        this.$moveByPage(-1, true);
+    }
+
+    /**
+     * Shifts the document to wherever "page down" is, as well as moving the cursor position.
+     **/
+    gotoPageDown() {
+       this.$moveByPage(1, false);
+    }
+
+    /**
+     * Shifts the document to wherever "page up" is, as well as moving the cursor position.
+     **/
+    gotoPageUp() {
+        this.$moveByPage(-1, false);
+    }
+
+    /**
+     * Scrolls the document to wherever "page down" is, without changing the cursor position.
+     **/
+    scrollPageDown() {
+        this.$moveByPage(1);
+    }
+
+    /**
+     * Scrolls the document to wherever "page up" is, without changing the cursor position.
+     **/
+    scrollPageUp() {
+        this.$moveByPage(-1);
+    }
+
+    /**
+     * Moves the editor to the specified row.
+     * @related VirtualRenderer.scrollToRow
+     **/
+    scrollToRow(row) {
+        this.renderer.scrollToRow(row);
+    }
+
+    /**
+     * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).
+     * @param {Number} line The line to scroll to
+     * @param {Boolean} center If `true`
+     * @param {Boolean} animate If `true` animates scrolling
+     * @param {Function} callback Function to be called when the animation has finished
+     *
+     *
+     * @related VirtualRenderer.scrollToLine
+     **/
+    scrollToLine(line, center, animate, callback) {
+        this.renderer.scrollToLine(line, center, animate, callback);
+    }
+
+    /**
+     * Attempts to center the current selection on the screen.
+     **/
+    centerSelection() {
+        var range = this.getSelectionRange();
+        var pos = {
+            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
+            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
+        };
+        this.renderer.alignCursor(pos, 0.5);
+    }
+
+    /**
+     * Gets the current position of the cursor.
+     * @returns {Object} An object that looks something like this:
+     *
+     * ```json
+     * { row: currRow, column: currCol }
+     * ```
+     *
+     * @related Selection.getCursor
+     **/
+    getCursorPosition() {
+        return this.selection.getCursor();
+    }
+
+    /**
+     * Returns the screen position of the cursor.
+     * @returns {Position}
+     * @related EditSession.documentToScreenPosition
+     **/
+    getCursorPositionScreen() {
+        return this.session.documentToScreenPosition(this.getCursorPosition());
+    }
+
+    /**
+     * {:Selection.getRange}
+     * @returns {Range}
+     * @related Selection.getRange
+     **/
+    getSelectionRange() {
+        return this.selection.getRange();
+    }
+    
+    /**
+     * Selects all the text in editor.
+     * @related Selection.selectAll
+     **/
+    selectAll() {
+        this.selection.selectAll();
+    }
+
+    /**
+     * {:Selection.clearSelection}
+     * @related Selection.clearSelection
+     **/
+    clearSelection() {
+        this.selection.clearSelection();
+    }
+
+    /**
+     * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.
+     * @param {Number} row The new row number
+     * @param {Number} column The new column number
+     * @related Selection.moveCursorTo
+     **/
+    moveCursorTo(row, column) {
+        this.selection.moveCursorTo(row, column);
+    }
+
+    /**
+     * Moves the cursor to the position indicated by `pos.row` and `pos.column`.
+     * @param {Position} pos An object with two properties, row and column
+     * @related Selection.moveCursorToPosition
+     **/
+    moveCursorToPosition(pos) {
+        this.selection.moveCursorToPosition(pos);
+    }
+
+    /**
+     * Moves the cursor's row and column to the next matching bracket or HTML tag.
+     *
+     **/
+    jumpToMatching(select, expand) {
+        var cursor = this.getCursorPosition();
+        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
+        var prevToken = iterator.getCurrentToken();
+        var tokenCount = 0;
+        if (prevToken && prevToken.type.indexOf('tag-name') !== -1) {
+            prevToken = iterator.stepBackward();
+        }
+        var token = prevToken || iterator.stepForward();
+
+        if (!token) return;
+
+        //get next closing tag or bracket
+        var matchType;
+        var found = false;
+        var depth = {};
+        var i = cursor.column - token.start;
+        var bracketType;
+        var brackets = {
+            ")": "(",
+            "(": "(",
+            "]": "[",
+            "[": "[",
+            "{": "{",
+            "}": "{"
+        };
+
+        do {
+            if (token.value.match(/[{}()\[\]]/g)) {
+                for (; i < token.value.length && !found; i++) {
+                    if (!brackets[token.value[i]]) {
+                        continue;
+                    }
+
+                    bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
+
+                    if (isNaN(depth[bracketType])) {
+                        depth[bracketType] = 0;
+                    }
+
+                    switch (token.value[i]) {
+                        case '(':
+                        case '[':
+                        case '{':
+                            depth[bracketType]++;
+                            break;
+                        case ')':
+                        case ']':
+                        case '}':
+                            depth[bracketType]--;
+
+                            if (depth[bracketType] === -1) {
+                                matchType = 'bracket';
+                                found = true;
+                            }
+                            break;
+                    }
+                }
+            }
+            else if (token.type.indexOf('tag-name') !== -1) {
+                if (isNaN(depth[token.value])) {
+                    depth[token.value] = 0;
+                }
+
+                if (prevToken.value === '<' && tokenCount > 1) {
+                    depth[token.value]++;
+                }
+                else if (prevToken.value === '= 0; --i) {
+            if(this.$tryReplace(ranges[i], replacement)) {
+                replaced++;
+            }
+        }
+
+        this.selection.setSelectionRange(selection);
+
+        return replaced;
+    }
+
+    $tryReplace(range, replacement) {
+        var input = this.session.getTextRange(range);
+        replacement = this.$search.replace(input, replacement);
+        if (replacement !== null) {
+            range.end = this.session.replace(range, replacement);
+            return range;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].
+     * @related Search.getOptions
+     * @returns {Object}
+     **/
+    getLastSearchOptions() {
+        return this.$search.getOptions();
+    }
+
+    /**
+     * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].
+     * @param {String|RegExp|Object} needle The text to search for (optional)
+     * @param {Object} options An object defining various search properties
+     * @param {Boolean} animate If `true` animate scrolling
+     * @related Search.find
+     **/
+    find(needle, options, animate) {
+        if (!options)
+            options = {};
+
+        if (typeof needle == "string" || needle instanceof RegExp)
+            options.needle = needle;
+        else if (typeof needle == "object")
+            oop.mixin(options, needle);
+
+        var range = this.selection.getRange();
+        if (options.needle == null) {
+            needle = this.session.getTextRange(range)
+                || this.$search.$options.needle;
+            if (!needle) {
+                range = this.session.getWordRange(range.start.row, range.start.column);
+                needle = this.session.getTextRange(range);
+            }
+            this.$search.set({needle: needle});
+        }
+
+        this.$search.set(options);
+        if (!options.start)
+            this.$search.set({start: range});
+
+        var newRange = this.$search.find(this.session);
+        if (options.preventScroll)
+            return newRange;
+        if (newRange) {
+            this.revealRange(newRange, animate);
+            return newRange;
+        }
+        // clear selection if nothing is found
+        if (options.backwards)
+            range.start = range.end;
+        else
+            range.end = range.start;
+        this.selection.setRange(range);
+    }
+
+    /**
+     * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].
+     * @param {Object} options search options
+     * @param {Boolean} animate If `true` animate scrolling
+     *
+     *
+     * @related Editor.find
+     **/
+    findNext(options, animate) {
+        this.find({skipCurrent: true, backwards: false}, options, animate);
+    }
+
+    /**
+     * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].
+     * @param {Object} options search options
+     * @param {Boolean} animate If `true` animate scrolling
+     *
+     *
+     * @related Editor.find
+     **/
+    findPrevious(options, animate) {
+        this.find(options, {skipCurrent: true, backwards: true}, animate);
+    }
+
+    revealRange(range, animate) {
+        this.session.unfold(range);
+        this.selection.setSelectionRange(range);
+
+        var scrollTop = this.renderer.scrollTop;
+        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
+        if (animate !== false)
+            this.renderer.animateScrolling(scrollTop);
+    }
+
+    /**
+     * {:UndoManager.undo}
+     * @related UndoManager.undo
+     **/
+    undo() {
+        this.session.getUndoManager().undo(this.session);
+        this.renderer.scrollCursorIntoView(null, 0.5);
+    }
+
+    /**
+     * {:UndoManager.redo}
+     * @related UndoManager.redo
+     **/
+    redo() {
+        this.session.getUndoManager().redo(this.session);
+        this.renderer.scrollCursorIntoView(null, 0.5);
+    }
+
+    /**
+     *
+     * Cleans up the entire editor.
+     **/
+    destroy() {
+        if (this.$toDestroy) {
+            this.$toDestroy.forEach(function(el) {
+                el.destroy();
+            });
+            this.$toDestroy = null;
+        }
+        if (this.$mouseHandler)
+            this.$mouseHandler.destroy();
+        this.renderer.destroy();
+        this._signal("destroy", this);
+        if (this.session)
+            this.session.destroy();
+        if (this._$emitInputEvent)
+            this._$emitInputEvent.cancel();
+        this.removeAllListeners();
+    }
+
+    /**
+     * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element
+     * @param {Boolean} enable default true
+     **/
+    setAutoScrollEditorIntoView(enable) {
+        if (!enable)
+            return;
+        var rect;
+        var self = this;
+        var shouldScroll = false;
+        if (!this.$scrollAnchor)
+            this.$scrollAnchor = document.createElement("div");
+        var scrollAnchor = this.$scrollAnchor;
+        scrollAnchor.style.cssText = "position:absolute";
+        this.container.insertBefore(scrollAnchor, this.container.firstChild);
+        var onChangeSelection = this.on("changeSelection", function() {
+            shouldScroll = true;
+        });
+        // needed to not trigger sync reflow
+        var onBeforeRender = this.renderer.on("beforeRender", function() {
+            if (shouldScroll)
+                rect = self.renderer.container.getBoundingClientRect();
+        });
+        var onAfterRender = this.renderer.on("afterRender", function() {
+            if (shouldScroll && rect && (self.isFocused()
+                || self.searchBox && self.searchBox.isFocused())
+            ) {
+                var renderer = self.renderer;
+                var pos = renderer.$cursorLayer.$pixelPos;
+                var config = renderer.layerConfig;
+                var top = pos.top - config.offset;
+                if (pos.top >= 0 && top + rect.top < 0) {
+                    shouldScroll = true;
+                } else if (pos.top < config.height &&
+                    pos.top + rect.top + config.lineHeight > window.innerHeight) {
+                    shouldScroll = false;
+                } else {
+                    shouldScroll = null;
+                }
+                if (shouldScroll != null) {
+                    scrollAnchor.style.top = top + "px";
+                    scrollAnchor.style.left = pos.left + "px";
+                    scrollAnchor.style.height = config.lineHeight + "px";
+                    scrollAnchor.scrollIntoView(shouldScroll);
+                }
+                shouldScroll = rect = null;
+            }
+        });
+        this.setAutoScrollEditorIntoView = function(enable) {
+            if (enable)
+                return;
+            delete this.setAutoScrollEditorIntoView;
+            this.off("changeSelection", onChangeSelection);
+            this.renderer.off("afterRender", onAfterRender);
+            this.renderer.off("beforeRender", onBeforeRender);
+        };
+    }
+
+
+    $resetCursorStyle() {
+        var style = this.$cursorStyle || "ace";
+        var cursorLayer = this.renderer.$cursorLayer;
+        if (!cursorLayer)
+            return;
+        cursorLayer.setSmoothBlinking(/smooth/.test(style));
+        cursorLayer.isBlinking = !this.$readOnly && style != "wide";
+        dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style));
+    }
+
+    /**
+     * opens a prompt displaying message
+     **/
+    prompt(message, options, callback) {
+        var editor = this;
+        config.loadModule("ace/ext/prompt", function (module) {
+            module.prompt(editor, message, options, callback);
+        });
+    }
+
+}
+
+Editor.$uid = 0;
+Editor.prototype.curOp = null;
+Editor.prototype.prevOp = {};
+// TODO use property on commands instead of this
+Editor.prototype.$mergeableCommands = ["backspace", "del", "insertstring"];
+Editor.prototype.$toggleWordPairs = [
+    ["first", "last"],
+    ["true", "false"],
+    ["yes", "no"],
+    ["width", "height"],
+    ["top", "bottom"],
+    ["right", "left"],
+    ["on", "off"],
+    ["x", "y"],
+    ["get", "set"],
+    ["max", "min"],
+    ["horizontal", "vertical"],
+    ["show", "hide"],
+    ["add", "remove"],
+    ["up", "down"],
+    ["before", "after"],
+    ["even", "odd"],
+    ["in", "out"],
+    ["inside", "outside"],
+    ["next", "previous"],
+    ["increase", "decrease"],
+    ["attach", "detach"],
+    ["&&", "||"],
+    ["==", "!="]
+];
+
+oop.implement(Editor.prototype, EventEmitter);
+
+
+config.defineOptions(Editor.prototype, "editor", {
+    selectionStyle: {
+        set: function(style) {
+            this.onSelectionChange();
+            this._signal("changeSelectionStyle", {data: style});
+        },
+        initialValue: "line"
+    },
+    highlightActiveLine: {
+        set: function() {this.$updateHighlightActiveLine();},
+        initialValue: true
+    },
+    highlightSelectedWord: {
+        set: function(shouldHighlight) {this.$onSelectionChange();},
+        initialValue: true
+    },
+    readOnly: {
+        set: function(readOnly) {
+            this.textInput.setReadOnly(readOnly);
+            this.$resetCursorStyle(); 
+        },
+        initialValue: false
+    },
+    copyWithEmptySelection: {
+        set: function(value) {
+            this.textInput.setCopyWithEmptySelection(value);
+        },
+        initialValue: false
+    },
+    cursorStyle: {
+        set: function(val) { this.$resetCursorStyle(); },
+        values: ["ace", "slim", "smooth", "wide"],
+        initialValue: "ace"
+    },
+    mergeUndoDeltas: {
+        values: [false, true, "always"],
+        initialValue: true
+    },
+    behavioursEnabled: {initialValue: true},
+    wrapBehavioursEnabled: {initialValue: true},
+    enableAutoIndent: {initialValue: true},
+    autoScrollEditorIntoView: {
+        set: function(val) {this.setAutoScrollEditorIntoView(val);}
+    },
+    keyboardHandler: {
+        set: function(val) { this.setKeyboardHandler(val); },
+        get: function() { return this.$keybindingId; },
+        handlesSet: true
+    },
+    value: {
+        set: function(val) { this.session.setValue(val); },
+        get: function() { return this.getValue(); },
+        handlesSet: true,
+        hidden: true
+    },
+    session: {
+        set: function(val) { this.setSession(val); },
+        get: function() { return this.session; },
+        handlesSet: true,
+        hidden: true
+    },
+    
+    showLineNumbers: {
+        set: function(show) {
+            this.renderer.$gutterLayer.setShowLineNumbers(show);
+            this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER);
+            if (show && this.$relativeLineNumbers)
+                relativeNumberRenderer.attach(this);
+            else
+                relativeNumberRenderer.detach(this);
+        },
+        initialValue: true
+    },
+    relativeLineNumbers: {
+        set: function(value) {
+            if (this.$showLineNumbers && value)
+                relativeNumberRenderer.attach(this);
+            else
+                relativeNumberRenderer.detach(this);
+        }
+    },
+    placeholder: {
+        set: function(message) {
+            if (!this.$updatePlaceholder) {
+                this.$updatePlaceholder = function() {
+                    var value = this.session && (this.renderer.$composition || this.getValue());
+                    if (value && this.renderer.placeholderNode) {
+                        this.renderer.off("afterRender", this.$updatePlaceholder);
+                        dom.removeCssClass(this.container, "ace_hasPlaceholder");
+                        this.renderer.placeholderNode.remove();
+                        this.renderer.placeholderNode = null;
+                    } else if (!value && !this.renderer.placeholderNode) {
+                        this.renderer.on("afterRender", this.$updatePlaceholder);
+                        dom.addCssClass(this.container, "ace_hasPlaceholder");
+                        var el = dom.createElement("div");
+                        el.className = "ace_placeholder";
+                        el.textContent = this.$placeholder || "";
+                        this.renderer.placeholderNode = el;
+                        this.renderer.content.appendChild(this.renderer.placeholderNode);
+                    } else if (!value && this.renderer.placeholderNode) {
+                        this.renderer.placeholderNode.textContent = this.$placeholder || "";
+                    }
+                }.bind(this);
+                this.on("input", this.$updatePlaceholder);
+            }
+            this.$updatePlaceholder();
+        }
+    },
+    enableKeyboardAccessibility: {
+        set: function(value) {
+            var blurCommand = {
+                name: "blurTextInput",
+                description: "Set focus to the editor content div to allow tabbing through the page",
+                bindKey: "Esc",
+                exec: function(editor) {
+                    editor.blur();
+                    editor.renderer.content.focus();
+                },
+                readOnly: true
+            };
+
+            var focusOnEnterKeyup = function (e) {
+                if (e.target == this.renderer.content && e.keyCode === keys['enter']){
+                    e.stopPropagation();
+                    e.preventDefault();
+                    this.focus();
+                }
+            };
+
+            var keyboardFocusClassName = "ace_keyboard-focus";
+
+            // Prevent focus to be captured when tabbing through the page. When focus is set to the content div, 
+            // press Enter key to give focus to Ace and press Esc to again allow to tab through the page.
+            if (value){
+                this.textInput.getElement().setAttribute("tabindex", -1);
+                this.renderer.content.setAttribute("tabindex", 0);
+                this.renderer.content.classList.add(keyboardFocusClassName);
+                this.renderer.content.setAttribute("aria-label",
+                    "Editor, press Enter key to start editing, press Escape key to exit"
+                );
+
+                this.renderer.content.addEventListener("keyup", focusOnEnterKeyup.bind(this));
+                this.commands.addCommand(blurCommand);
+            } else {
+                this.textInput.getElement().setAttribute("tabindex", 0);
+                this.renderer.content.setAttribute("tabindex", -1);
+                this.renderer.content.classList.remove(keyboardFocusClassName);
+                this.renderer.content.setAttribute("aria-label", "");
+            
+                this.renderer.content.removeEventListener("keyup", focusOnEnterKeyup.bind(this));
+                this.commands.removeCommand(blurCommand);
+            }
+        },
+        initialValue: false
+    },
+    customScrollbar: "renderer",
+    hScrollBarAlwaysVisible: "renderer",
+    vScrollBarAlwaysVisible: "renderer",
+    highlightGutterLine: "renderer",
+    animatedScroll: "renderer",
+    showInvisibles: "renderer",
+    showPrintMargin: "renderer",
+    printMarginColumn: "renderer",
+    printMargin: "renderer",
+    fadeFoldWidgets: "renderer",
+    showFoldWidgets: "renderer",
+    displayIndentGuides: "renderer",
+    highlightIndentGuides: "renderer",
+    showGutter: "renderer",
+    fontSize: "renderer",
+    fontFamily: "renderer",
+    maxLines: "renderer",
+    minLines: "renderer",
+    scrollPastEnd: "renderer",
+    fixedWidthGutter: "renderer",
+    theme: "renderer",
+    hasCssTransforms: "renderer",
+    maxPixelHeight: "renderer",
+    useTextareaForIME: "renderer",
+    useResizeObserver: "renderer",
+    useSvgGutterIcons: "renderer",
+
+    scrollSpeed: "$mouseHandler",
+    dragDelay: "$mouseHandler",
+    dragEnabled: "$mouseHandler",
+    focusTimeout: "$mouseHandler",
+    tooltipFollowsMouse: "$mouseHandler",
+
+    firstLineNumber: "session",
+    overwrite: "session",
+    newLineMode: "session",
+    useWorker: "session",
+    useSoftTabs: "session",
+    navigateWithinSoftTabs: "session",
+    tabSize: "session",
+    wrap: "session",
+    indentedSoftWrap: "session",
+    foldStyle: "session",
+    mode: "session"
+});
+
+
+var relativeNumberRenderer = {
+    getText: function(session, row) {
+        return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? "\xb7" : ""))) + "";
+    },
+    getWidth: function(session, lastLineNumber, config) {
+        return Math.max(
+            lastLineNumber.toString().length,
+            (config.lastRow + 1).toString().length,
+            2
+        ) * config.characterWidth;
+    },
+    update: function(e, editor) {
+        editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER);
+    },
+    attach: function(editor) {
+        editor.renderer.$gutterLayer.$renderer = this;
+        editor.on("changeSelection", this.update);
+        this.update(null, editor);
+    },
+    detach: function(editor) {
+        if (editor.renderer.$gutterLayer.$renderer == this)
+            editor.renderer.$gutterLayer.$renderer = null;
+        editor.off("changeSelection", this.update);
+        this.update(null, editor);
+    }
+};
+
+exports.Editor = Editor;
diff --git a/demo/diff/examples/editor.40.js b/demo/diff/examples/editor.40.js
new file mode 100644
index 00000000000..099fca450b8
--- /dev/null
+++ b/demo/diff/examples/editor.40.js
@@ -0,0 +1,3159 @@
+"use strict";
+
+/**
+ * @typedef {import("./virtual_renderer").VirtualRenderer} VirtualRenderer
+ * @typedef {import("./selection").Selection} Selection
+ * @typedef {import("../ace-internal").Ace.Point} Point
+ * @typedef {import("../ace-internal").Ace.SearchOptions} SearchOptions
+ */
+
+var oop = require("./lib/oop");
+var dom = require("./lib/dom");
+var lang = require("./lib/lang");
+var useragent = require("./lib/useragent");
+var TextInput = require("./keyboard/textinput").TextInput;
+var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
+var FoldHandler = require("./mouse/fold_handler").FoldHandler;
+var KeyBinding = require("./keyboard/keybinding").KeyBinding;
+var EditSession = require("./edit_session").EditSession;
+var Search = require("./search").Search;
+var Range = require("./range").Range;
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+var CommandManager = require("./commands/command_manager").CommandManager;
+var defaultCommands = require("./commands/default_commands").commands;
+var config = require("./config");
+var TokenIterator = require("./token_iterator").TokenIterator;
+var GutterKeyboardHandler = require("./keyboard/gutter_handler").GutterKeyboardHandler;
+var nls = require("./config").nls;
+
+var clipboard = require("./clipboard");
+var keys = require('./lib/keys');
+
+var event = require("./lib/event");
+var HoverTooltip = require("./tooltip").HoverTooltip;
+
+/**
+ * The main entry point into the Ace functionality.
+ *
+ * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.
+ *
+ * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.
+ **/
+class Editor {
+    /**
+     * Creates a new `Editor` object.
+     *
+     * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything
+     * @param {EditSession} [session] The `EditSession` to refer to
+     * @param {Partial} [options] The default options
+     **/
+    constructor(renderer, session, options) {
+        /**@type{EditSession}*/this.session;
+        this.$toDestroy = [];
+
+        var container = renderer.getContainerElement();
+        /**@type {HTMLElement & {env?:any, value?:any}}*/
+        this.container = container;
+        /**@type {VirtualRenderer}*/
+        this.renderer = renderer;
+        /**@type {string}*/
+        this.id = "editor" + (++Editor.$uid);
+        this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
+        if (typeof document == "object") {
+            this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
+            this.renderer.textarea = this.textInput.getElement();
+            // TODO detect touch event support
+            /**@type {MouseHandler}*/
+            this.$mouseHandler = new MouseHandler(this);
+            new FoldHandler(this);
+        }
+        /**@type {KeyBinding}*/
+        this.keyBinding = new KeyBinding(this);
+        /**@type {Search}*/
+        this.$search = new Search().set({
+            wrap: true
+        });
+
+        this.$historyTracker = this.$historyTracker.bind(this);
+        this.commands.on("exec", this.$historyTracker);
+
+        this.$initOperationListeners();
+
+        this._$emitInputEvent = lang.delayedCall(function() {
+            this._signal("input", {});
+            if (this.session && !this.session.destroyed)
+                this.session.bgTokenizer.scheduleStart();
+        }.bind(this));
+
+        this.on("change", function(_, _self) {
+            _self._$emitInputEvent.schedule(31);
+        });
+
+        this.setSession(session || options && options.session || new EditSession(""));
+        config.resetOptions(this);
+        if (options)
+            this.setOptions(options);
+        config._signal("editor", this);
+    }
+
+    $initOperationListeners() {
+        this.commands.on("exec", this.startOperation.bind(this), true);
+        this.commands.on("afterExec", this.endOperation.bind(this), true);
+    }
+
+    startOperation(commandEvent) {
+        this.session.startOperation(commandEvent);
+    }
+
+    /**
+     * @arg e
+     */
+    endOperation(e) {
+        this.session.endOperation(e);
+    }
+
+    onStartOperation(commandEvent) {
+        this.curOp = this.session.curOp;
+        this.curOp.scrollTop = this.renderer.scrollTop;
+        this.prevOp = this.session.prevOp;
+
+        if (!commandEvent) {
+            this.previousCommand = null;
+        }
+    }
+
+    /**
+     * @arg e
+     */
+    onEndOperation(e) {
+        if (this.curOp && this.session) {
+            if (e && e.returnValue === false) {
+                this.curOp = null;
+                return;
+            }
+
+            this._signal("beforeEndOperation");
+            if (!this.curOp) return;
+
+            var command = this.curOp.command;
+            var scrollIntoView = command && command.scrollIntoView;
+            if (scrollIntoView) {
+                switch (scrollIntoView) {
+                    case "center-animate":
+                        scrollIntoView = "animate";
+                        /* fall through */
+                    case "center":
+                        this.renderer.scrollCursorIntoView(null, 0.5);
+                        break;
+                    case "animate":
+                    case "cursor":
+                        this.renderer.scrollCursorIntoView();
+                        break;
+                    case "selectionPart":
+                        var range = this.selection.getRange();
+                        var config = this.renderer.layerConfig;
+                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {
+                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);
+                        }
+                        break;
+                    default:
+                        break;
+                }
+                if (scrollIntoView == "animate")
+                    this.renderer.animateScrolling(this.curOp.scrollTop);
+            }
+
+            this.$lastSel = this.session.selection.toJSON();
+            this.prevOp = this.curOp;
+            this.curOp = null;
+        }
+    }
+
+    /**
+     * @param e
+     */
+    $historyTracker(e) {
+        if (!this.$mergeUndoDeltas)
+            return;
+
+        var prev = this.prevOp;
+        var mergeableCommands = this.$mergeableCommands;
+        // previous command was the same
+        var shouldMerge = prev.command && (e.command.name == prev.command.name);
+        if (e.command.name == "insertstring") {
+            var text = e.args;
+            if (this.mergeNextCommand === undefined)
+                this.mergeNextCommand = true;
+
+            shouldMerge = shouldMerge
+                && this.mergeNextCommand // previous command allows to coalesce with
+                && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type
+
+            this.mergeNextCommand = true;
+        } else {
+            shouldMerge = shouldMerge
+                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable
+        }
+
+        if (
+            this.$mergeUndoDeltas != "always"
+            && Date.now() - this.sequenceStartTime > 2000
+        ) {
+            shouldMerge = false; // the sequence is too long
+        }
+
+        if (shouldMerge)
+            this.session.mergeUndoDeltas = true;
+        else if (mergeableCommands.indexOf(e.command.name) !== -1)
+            this.sequenceStartTime = Date.now();
+    }
+
+    /**
+     * Sets a new key handler, such as "vim" or "windows".
+     * @param {String | import("../ace-internal").Ace.KeyboardHandler | null} keyboardHandler The new key handler
+     * @param {() => void} [cb]
+     **/
+    setKeyboardHandler(keyboardHandler, cb) {
+        if (keyboardHandler && typeof keyboardHandler === "string" && keyboardHandler != "ace") {
+            this.$keybindingId = keyboardHandler;
+            var _self = this;
+            config.loadModule(["keybinding", keyboardHandler], function(module) {
+                if (_self.$keybindingId == keyboardHandler)
+                    _self.keyBinding.setKeyboardHandler(module && module.handler);
+                cb && cb();
+            });
+        } else {
+            this.$keybindingId = null;
+            // @ts-ignore
+            this.keyBinding.setKeyboardHandler(keyboardHandler);
+            cb && cb();
+        }
+    }
+
+    /**
+     * Returns the keyboard handler, such as "vim" or "windows".
+     * @returns {Object}
+     **/
+    getKeyboardHandler() {
+        return this.keyBinding.getKeyboardHandler();
+    }
+
+
+
+    /**
+     * Sets a new editsession to use. This method also emits the `'changeSession'` event.
+     * @param {EditSession} [session] The new session to use
+     **/
+    setSession(session) {
+        if (this.session == session)
+            return;
+
+        // make sure operationEnd events are not emitted to wrong session
+        if (this.curOp) this.endOperation();
+        this.curOp = {};
+
+        var oldSession = this.session;
+        if (oldSession) {
+            this.session.off("change", this.$onDocumentChange);
+            this.session.off("changeMode", this.$onChangeMode);
+            this.session.off("tokenizerUpdate", this.$onTokenizerUpdate);
+            this.session.off("changeTabSize", this.$onChangeTabSize);
+            this.session.off("changeWrapLimit", this.$onChangeWrapLimit);
+            this.session.off("changeWrapMode", this.$onChangeWrapMode);
+            this.session.off("changeFold", this.$onChangeFold);
+            this.session.off("changeFrontMarker", this.$onChangeFrontMarker);
+            this.session.off("changeBackMarker", this.$onChangeBackMarker);
+            this.session.off("changeBreakpoint", this.$onChangeBreakpoint);
+            this.session.off("changeAnnotation", this.$onChangeAnnotation);
+            this.session.off("changeOverwrite", this.$onCursorChange);
+            this.session.off("changeScrollTop", this.$onScrollTopChange);
+            this.session.off("changeScrollLeft", this.$onScrollLeftChange);
+            this.session.off("startOperation", this.$onStartOperation);
+            this.session.off("endOperation", this.$onEndOperation);
+
+            var selection = this.session.getSelection();
+            selection.off("changeCursor", this.$onCursorChange);
+            selection.off("changeSelection", this.$onSelectionChange);
+        }
+
+        this.session = session;
+        if (session) {
+            this.$onDocumentChange = this.onDocumentChange.bind(this);
+            session.on("change", this.$onDocumentChange);
+            this.renderer.setSession(session);
+
+            this.$onChangeMode = this.onChangeMode.bind(this);
+            session.on("changeMode", this.$onChangeMode);
+
+            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
+            session.on("tokenizerUpdate", this.$onTokenizerUpdate);
+
+            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
+            session.on("changeTabSize", this.$onChangeTabSize);
+
+            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
+            session.on("changeWrapLimit", this.$onChangeWrapLimit);
+
+            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
+            session.on("changeWrapMode", this.$onChangeWrapMode);
+
+            this.$onChangeFold = this.onChangeFold.bind(this);
+            session.on("changeFold", this.$onChangeFold);
+
+            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
+            this.session.on("changeFrontMarker", this.$onChangeFrontMarker);
+
+            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
+            this.session.on("changeBackMarker", this.$onChangeBackMarker);
+
+            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
+            this.session.on("changeBreakpoint", this.$onChangeBreakpoint);
+
+            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
+            this.session.on("changeAnnotation", this.$onChangeAnnotation);
+
+            this.$onCursorChange = this.onCursorChange.bind(this);
+            this.session.on("changeOverwrite", this.$onCursorChange);
+
+            this.$onScrollTopChange = this.onScrollTopChange.bind(this);
+            this.session.on("changeScrollTop", this.$onScrollTopChange);
+
+            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
+            this.session.on("changeScrollLeft", this.$onScrollLeftChange);
+
+            this.selection = session.getSelection();
+            this.selection.on("changeCursor", this.$onCursorChange);
+
+            this.$onSelectionChange = this.onSelectionChange.bind(this);
+            this.selection.on("changeSelection", this.$onSelectionChange);
+
+            this.$onStartOperation = this.onStartOperation.bind(this);
+            this.session.on("startOperation", this.$onStartOperation);
+            this.$onEndOperation = this.onEndOperation.bind(this);
+            this.session.on("endOperation", this.$onEndOperation);
+
+            this.onChangeMode();
+
+            this.onCursorChange();
+
+            this.onScrollTopChange();
+            this.onScrollLeftChange();
+            this.onSelectionChange();
+            this.onChangeFrontMarker();
+            this.onChangeBackMarker();
+            this.onChangeBreakpoint();
+            this.onChangeAnnotation();
+            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
+            this.renderer.updateFull();
+        } else {
+            this.selection = null;
+            this.renderer.setSession(session);
+        }
+
+        this._signal("changeSession", {
+            session: session,
+            oldSession: oldSession
+        });
+
+        this.curOp = null;
+
+        oldSession && oldSession._signal("changeEditor", {oldEditor: this});
+        if (oldSession) oldSession.$editor = null;
+        session && session._signal("changeEditor", {editor: this});
+        if (session) session.$editor = this;
+
+        if (session && !session.destroyed)
+            session.bgTokenizer.scheduleStart();
+    }
+
+    /**
+     * Returns the current session being used.
+     * @returns {EditSession}
+     **/
+    getSession() {
+        return this.session;
+    }
+
+    /**
+     * Sets the current document to `val`.
+     * @param {String} val The new value to set for the document
+     * @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
+     *
+     * @returns {String} The current document value
+     * @related Document.setValue
+     **/
+    setValue(val, cursorPos) {
+        this.session.doc.setValue(val);
+
+        if (!cursorPos)
+            this.selectAll();
+        else if (cursorPos == 1)
+            this.navigateFileEnd();
+        else if (cursorPos == -1)
+            this.navigateFileStart();
+
+        return val;
+    }
+
+    /**
+     * Returns the current session's content.
+     *
+     * @returns {String}
+     * @related EditSession.getValue
+     **/
+    getValue() {
+        return this.session.getValue();
+    }
+
+    /**
+     *
+     * Returns the currently highlighted selection.
+     * @returns {Selection} The selection object
+     **/
+    getSelection() {
+        return this.selection;
+    }
+
+    /**
+     * {:VirtualRenderer.onResize}
+     * @param {Boolean} [force] If `true`, recomputes the size, even if the height and width haven't changed
+     * @related VirtualRenderer.onResize
+     **/
+    resize(force) {
+        this.renderer.onResize(force);
+    }
+
+    /**
+     * {:VirtualRenderer.setTheme}
+     * @param {string | import("../ace-internal").Ace.Theme} theme The path to a theme
+     * @param {() => void} [cb] optional callback called when theme is loaded
+     **/
+    setTheme(theme, cb) {
+        this.renderer.setTheme(theme, cb);
+    }
+
+    /**
+     * {:VirtualRenderer.getTheme}
+     *
+     * @returns {String} The set theme
+     * @related VirtualRenderer.getTheme
+     **/
+    getTheme() {
+        return this.renderer.getTheme();
+    }
+
+    /**
+     * {:VirtualRenderer.setStyle}
+     * @param {String} style A class name
+     * @related VirtualRenderer.setStyle
+     **/
+    setStyle(style) {
+        this.renderer.setStyle(style);
+    }
+
+    /**
+     * {:VirtualRenderer.unsetStyle}
+     * @related VirtualRenderer.unsetStyle
+     * @param {string} style
+     */
+    unsetStyle(style) {
+        this.renderer.unsetStyle(style);
+    }
+
+    /**
+     * Gets the current font size of the editor text.
+     * @return {string | number}
+     */
+    getFontSize() {
+        return this.getOption("fontSize") ||
+           dom.computedStyle(this.container).fontSize;
+    }
+
+    /**
+     * Set a new font size (in pixels) for the editor text.
+     * @param {String | number} size A font size ( _e.g._ "12px")
+     **/
+    setFontSize(size) {
+        this.setOption("fontSize", size);
+    }
+
+    $highlightBrackets() {
+        if (this.$highlightPending) {
+            return;
+        }
+
+        // perform highlight async to not block the browser during navigation
+        var self = this;
+        this.$highlightPending = true;
+        setTimeout(function () {
+            self.$highlightPending = false;
+            var session = self.session;
+            if (!session || session.destroyed) return;
+            if (session.$bracketHighlight) {
+                session.$bracketHighlight.markerIds.forEach(function(id) {
+                    session.removeMarker(id);
+                });
+                session.$bracketHighlight = null;
+            }
+            var pos = self.getCursorPosition();
+            var handler = self.getKeyboardHandler();
+            var isBackwards = handler && handler.$getDirectionForHighlight && handler.$getDirectionForHighlight(self);
+            var ranges = session.getMatchingBracketRanges(pos, isBackwards);
+
+            if (!ranges) {
+                var iterator = new TokenIterator(session, pos.row, pos.column);
+                var token = iterator.getCurrentToken();
+
+                if (token && /\b(?:tag-open|tag-name)/.test(token.type)) {
+                    var tagNamesRanges = session.getMatchingTags(pos);
+                    if (tagNamesRanges) {
+                        ranges = [
+                            tagNamesRanges.openTagName.isEmpty() ? tagNamesRanges.openTag : tagNamesRanges.openTagName,
+                            tagNamesRanges.closeTagName.isEmpty() ? tagNamesRanges.closeTag : tagNamesRanges.closeTagName
+                        ];
+                    }
+                }
+            }
+            if (!ranges && session.$mode.getMatching)
+                ranges = session.$mode.getMatching(self.session);
+            if (!ranges) {
+                if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();
+                return;
+            }
+
+            var markerType = "ace_bracket";
+            if (!Array.isArray(ranges)) {
+                ranges = [ranges];
+            } else if (ranges.length == 1) {
+                markerType = "ace_error_bracket";
+            }
+
+            // show adjacent ranges as one
+            if (ranges.length == 2) {
+                if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)
+                    ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];
+                else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)
+                    ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];
+            }
+
+            session.$bracketHighlight = {
+                ranges: ranges,
+                markerIds: ranges.map(function(range) {
+                    return session.addMarker(range, markerType, "text");
+                })
+            };
+            if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();
+        }, 50);
+    }
+
+    /**
+     *
+     * Brings the current `textInput` into focus.
+     **/
+    focus() {
+        this.textInput.focus();
+    }
+
+    /**
+     * Returns `true` if the current `textInput` is in focus.
+     * @return {Boolean}
+     **/
+    isFocused() {
+        return this.textInput.isFocused();
+    }
+
+    /**
+     *
+     * Blurs the current `textInput`.
+     **/
+    blur() {
+        this.textInput.blur();
+    }
+
+    /**
+     * Emitted once the editor comes into focus.
+     * @internal
+     **/
+    onFocus(e) {
+        if (this.$isFocused)
+            return;
+        this.$isFocused = true;
+        this.renderer.showCursor();
+        this.renderer.visualizeFocus();
+        this._emit("focus", e);
+    }
+
+    /**
+     * Emitted once the editor has been blurred.
+     * @internal
+     **/
+    onBlur(e) {
+        if (!this.$isFocused)
+            return;
+        this.$isFocused = false;
+        this.renderer.hideCursor();
+        this.renderer.visualizeBlur();
+        this._emit("blur", e);
+    }
+
+    /**
+     */
+    $cursorChange() {
+        this.renderer.updateCursor();
+        this.$highlightBrackets();
+        this.$updateHighlightActiveLine();
+    }
+
+    /**
+     * Emitted whenever the document is changed.
+     * @param {import("../ace-internal").Ace.Delta} delta Contains a single property, `data`, which has the delta of changes
+     * @internal
+     **/
+    onDocumentChange(delta) {
+        // Rerender and emit "change" event.
+        var wrap = this.session.$useWrapMode;
+        var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);
+        this.renderer.updateLines(delta.start.row, lastRow, wrap);
+
+        this._signal("change", delta);
+
+        // Update cursor because tab characters can influence the cursor position.
+        this.$cursorChange();
+    }
+
+    /**
+     * @internal
+     */
+    onTokenizerUpdate(e) {
+        var rows = e.data;
+        this.renderer.updateLines(rows.first, rows.last);
+    }
+
+    /**
+     * @internal
+     */
+    onScrollTopChange() {
+        this.renderer.scrollToY(this.session.getScrollTop());
+    }
+
+    /**
+     * @internal
+     */
+    onScrollLeftChange() {
+        this.renderer.scrollToX(this.session.getScrollLeft());
+    }
+
+    /**
+     * Emitted when the selection changes.
+     * @internal
+     **/
+    onCursorChange() {
+        this.$cursorChange();
+        this._signal("changeSelection");
+    }
+
+    /**
+     */
+    $updateHighlightActiveLine() {
+        var session = this.getSession();
+        /**@type {Point|false}*/
+        var highlight;
+        if (this.$highlightActiveLine) {
+            if (this.$selectionStyle != "line" || !this.selection.isMultiLine())
+                highlight = this.getCursorPosition();
+            if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty())
+                highlight = false;
+            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))
+                highlight = false;
+        }
+
+        if (session.$highlightLineMarker && !highlight) {
+            session.removeMarker(session.$highlightLineMarker.id);
+            session.$highlightLineMarker = null;
+        } else if (!session.$highlightLineMarker && highlight) {
+            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
+            range.id = session.addMarker(range, "ace_active-line", "screenLine");
+            session.$highlightLineMarker = range;
+        } else if (highlight) {
+            session.$highlightLineMarker.start.row = highlight.row;
+            session.$highlightLineMarker.end.row = highlight.row;
+            session.$highlightLineMarker.start.column = highlight.column;
+            session._signal("changeBackMarker");
+        }
+    }
+
+    /**
+     * @param e
+     * @internal
+     */
+    onSelectionChange(e) {
+        var session = this.session;
+
+        if (session.$selectionMarker) {
+            session.removeMarker(session.$selectionMarker);
+        }
+        session.$selectionMarker = null;
+
+        if (!this.selection.isEmpty()) {
+            var range = this.selection.getRange();
+            var style = this.getSelectionStyle();
+            session.$selectionMarker = session.addMarker(range, "ace_selection", style);
+        } else {
+            this.$updateHighlightActiveLine();
+        }
+
+        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();
+        this.session.highlight(re);
+
+        this._signal("changeSelection");
+    }
+
+    $getSelectionHighLightRegexp() {
+        var session = this.session;
+
+        var selection = this.getSelectionRange();
+        if (selection.isEmpty() || selection.isMultiLine())
+            return;
+
+        var startColumn = selection.start.column;
+        var endColumn = selection.end.column;
+        var line = session.getLine(selection.start.row);
+
+        var needle = line.substring(startColumn, endColumn);
+        // maximum allowed size for regular expressions in 32000,
+        // but getting close to it has significant impact on the performance
+        if (needle.length > 5000 || !/[\w\d]/.test(needle))
+            return;
+
+        var re = this.$search.$assembleRegExp({
+            wholeWord: true,
+            caseSensitive: true,
+            needle: needle
+        });
+
+        var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1);
+        if (!re.test(wordWithBoundary))
+            return;
+
+        return re;
+    }
+
+    /**
+     * @internal
+     */
+    onChangeFrontMarker() {
+        this.renderer.updateFrontMarkers();
+    }
+
+    /**
+     * @internal
+     */
+    onChangeBackMarker() {
+        this.renderer.updateBackMarkers();
+    }
+
+    /**
+     * @internal
+     */
+    onChangeBreakpoint() {
+        this.renderer.updateBreakpoints();
+    }
+
+    /**
+     * @internal
+     */
+    onChangeAnnotation() {
+        this.renderer.setAnnotations(this.session.getAnnotations());
+    }
+
+    /**
+     * @param e
+     * @internal
+     */
+    onChangeMode (e) {
+        this.renderer.updateText();
+        this._emit("changeMode", e);
+    }
+
+    /**
+     * @internal
+     */
+    onChangeWrapLimit() {
+        this.renderer.updateFull();
+    }
+
+    /**
+     * @internal
+     */
+    onChangeWrapMode() {
+        this.renderer.onResize(true);
+    }
+
+
+    /**
+     * @internal
+     */
+    onChangeFold() {
+        // Update the active line marker as due to folding changes the current
+        // line range on the screen might have changed.
+        this.$updateHighlightActiveLine();
+        // TODO: This might be too much updating. Okay for now.
+        this.renderer.updateFull();
+    }
+
+
+    /**
+     * Returns the string of text currently highlighted.
+     * @returns {String}
+     **/
+    getSelectedText() {
+        return this.session.getTextRange(this.getSelectionRange());
+    }
+
+
+    /**
+     * Returns the string of text currently highlighted.
+     * @returns {String}
+     **/
+    getCopyText () {
+        var text = this.getSelectedText();
+        var nl = this.session.doc.getNewLineCharacter();
+        var copyLine= false;
+        if (!text && this.$copyWithEmptySelection) {
+            copyLine = true;
+            var ranges = this.selection.getAllRanges();
+            for (var i = 0; i < ranges.length; i++) {
+                var range = ranges[i];
+                if (i && ranges[i - 1].start.row == range.start.row)
+                    continue;
+                text += this.session.getLine(range.start.row) + nl;
+            }
+        }
+        var e = {text: text};
+        this._signal("copy", e);
+        clipboard.lineMode = copyLine ? e.text : false;
+        return e.text;
+    }
+
+    /**
+     * Called whenever a text "copy" happens.
+     * @internal
+     **/
+    onCopy() {
+        this.commands.exec("copy", this);
+    }
+
+    /**
+     * Called whenever a text "cut" happens.
+     * @internal
+     **/
+    onCut() {
+        this.commands.exec("cut", this);
+    }
+
+
+    /**
+     * Called whenever a text "paste" happens.
+     * @param {String} text The pasted text
+     * @param {ClipboardEvent} [event]
+     * @internal
+     **/
+    onPaste(text, event) {
+        var e = {text: text, event: event};
+        this.commands.exec("paste", this, e);
+    }
+
+    /**
+     *
+     * @param {string | {text: string, event?: ClipboardEvent}} e
+     * @returns {boolean}
+     */
+    $handlePaste(e) {
+        if (typeof e == "string")
+            e = {text: e};
+        this._signal("paste", e);
+        var text = e.text;
+
+        var lineMode = text === clipboard.lineMode;
+        var session = this.session;
+        if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {
+            if (lineMode)
+                session.insert({ row: this.selection.lead.row, column: 0 }, text);
+            else
+                this.insert(text);
+        } else if (lineMode) {
+            this.selection.rangeList.ranges.forEach(function(range) {
+                session.insert({ row: range.start.row, column: 0 }, text);
+            });
+        } else {
+            var lines = text.split(/\r\n|\r|\n/);
+            var ranges = this.selection.rangeList.ranges;
+
+            var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]);
+            if (lines.length != ranges.length || isFullLine)
+                return this.commands.exec("insertstring", this, text);
+
+            for (var i = ranges.length; i--;) {
+                var range = ranges[i];
+                if (!range.isEmpty())
+                    session.remove(range);
+
+                session.insert(range.start, lines[i]);
+            }
+        }
+    }
+
+    /**
+     *
+     * @param {string | string[]} command
+     * @param [args]
+     * @return {boolean}
+     */
+    execCommand(command, args) {
+        return this.commands.exec(command, this, args);
+    }
+
+    /**
+     * Inserts `text` into wherever the cursor is pointing.
+     * @param {String} text The new text to add
+     * @param {boolean} [pasted]
+     **/
+    insert(text, pasted) {
+        var session = this.session;
+        var mode = session.getMode();
+        var cursor = this.getCursorPosition();
+
+        if (this.getBehavioursEnabled() && !pasted) {
+            // Get a transform if the current mode wants one.
+            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
+            if (transform) {
+                if (text !== transform.text) {
+                    // keep automatic insertion in a separate delta, unless it is in multiselect mode
+                    if (!this.inVirtualSelectionMode) {
+                        this.session.mergeUndoDeltas = false;
+                        this.mergeNextCommand = false;
+                    }
+                }
+                text = transform.text;
+
+            }
+        }
+
+        if (text == "\t")
+            text = this.session.getTabString();
+
+        // remove selected text
+        if (!this.selection.isEmpty()) {
+            var range = this.getSelectionRange();
+            cursor = this.session.remove(range);
+            this.clearSelection();
+        }
+        else if (this.session.getOverwrite() && text.indexOf("\n") == -1) {
+            var range = Range.fromPoints(cursor, cursor);
+            range.end.column += text.length;
+            this.session.remove(range);
+        }
+
+        if (text == "\n" || text == "\r\n") {
+            var line = session.getLine(cursor.row);
+            if (cursor.column > line.search(/\S|$/)) {
+                var d = line.substr(cursor.column).search(/\S|$/);
+                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);
+            }
+        }
+        this.clearSelection();
+
+        var start = cursor.column;
+        var lineState = session.getState(cursor.row);
+        var line = session.getLine(cursor.row);
+        var shouldOutdent = mode.checkOutdent(lineState, line, text);
+        session.insert(cursor, text);
+
+        if (transform && transform.selection) {
+            if (transform.selection.length == 2) { // Transform relative to the current column
+                this.selection.setSelectionRange(
+                    new Range(cursor.row, start + transform.selection[0],
+                              cursor.row, start + transform.selection[1]));
+            } else { // Transform relative to the current row.
+                this.selection.setSelectionRange(
+                    new Range(cursor.row + transform.selection[0],
+                              transform.selection[1],
+                              cursor.row + transform.selection[2],
+                              transform.selection[3]));
+            }
+        }
+        if (this.$enableAutoIndent) {
+            if (session.getDocument().isNewLine(text)) {
+                var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
+
+                session.insert({row: cursor.row+1, column: 0}, lineIndent);
+            }
+            if (shouldOutdent)
+                mode.autoOutdent(lineState, session, cursor.row);
+        }
+    }
+
+    autoIndent() {
+        var session = this.session;
+        var mode = session.getMode();
+
+        var ranges = this.selection.isEmpty()
+            ? [new Range(0, 0, session.doc.getLength() - 1, 0)]
+            : this.selection.getAllRanges();
+
+        /**@type{string|string[]}*/
+        var prevLineState = "";
+        var prevLine = "";
+        var lineIndent = "";
+        var tab = session.getTabString();
+        for (var i = 0; i < ranges.length; i++) {
+            var startRow = ranges[i].start.row;
+            var endRow = ranges[i].end.row;
+
+            for (var row = startRow; row <= endRow; row++) {
+                if (row > 0) {
+                    prevLineState = session.getState(row - 1);
+                    prevLine = session.getLine(row - 1);
+                    lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab);
+                }
+
+                var line = session.getLine(row);
+                var currIndent = mode.$getIndent(line);
+                if (lineIndent !== currIndent) {
+                    if (currIndent.length > 0) {
+                        var range = new Range(row, 0, row, currIndent.length);
+                        session.remove(range);
+                    }
+                    if (lineIndent.length > 0) {
+                        session.insert({row: row, column: 0}, lineIndent);
+                    }
+                }
+
+                mode.autoOutdent(prevLineState, session, row);
+            }
+        }
+    }
+
+    /**
+     *
+     * @param text
+     * @param composition
+     * @returns {*}
+     * @internal
+     */
+    onTextInput(text, composition) {
+        if (!composition)
+            return this.keyBinding.onTextInput(text);
+
+        this.startOperation({command: { name: "insertstring" }});
+        var applyComposition = this.applyComposition.bind(this, text, composition);
+        if (this.selection.rangeCount)
+            this.forEachSelection(applyComposition);
+        else
+            applyComposition();
+        this.endOperation();
+    }
+
+    /**
+     * @param {string} [text]
+     * @param {any} [composition]
+     */
+    applyComposition(text, composition) {
+        if (composition.extendLeft || composition.extendRight) {
+            var r = this.selection.getRange();
+            r.start.column -= composition.extendLeft;
+            r.end.column += composition.extendRight;
+            if (r.start.column < 0) {
+                r.start.row--;
+                r.start.column += this.session.getLine(r.start.row).length + 1;
+            }
+            this.selection.setRange(r);
+            if (!text && !r.isEmpty())
+                this.remove();
+        }
+        if (text || !this.selection.isEmpty())
+            this.insert(text, true);
+        if (composition.restoreStart || composition.restoreEnd) {
+            var r = this.selection.getRange();
+            r.start.column -= composition.restoreStart;
+            r.end.column -= composition.restoreEnd;
+            this.selection.setRange(r);
+        }
+    }
+
+    /**
+     * @internal
+     */
+    onCommandKey(e, hashId, keyCode) {
+        return this.keyBinding.onCommandKey(e, hashId, keyCode);
+    }
+
+    /**
+     * 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.
+     * @param {Boolean} overwrite Defines whether or not to set overwrites
+     * @related EditSession.setOverwrite
+     **/
+    setOverwrite(overwrite) {
+        this.session.setOverwrite(overwrite);
+    }
+
+    /**
+     * Returns `true` if overwrites are enabled; `false` otherwise.
+     * @returns {Boolean}
+     * @related EditSession.getOverwrite
+     **/
+    getOverwrite() {
+        return this.session.getOverwrite();
+    }
+
+    /**
+     * Sets the value of overwrite to the opposite of whatever it currently is.
+     * @related EditSession.toggleOverwrite
+     **/
+    toggleOverwrite() {
+        this.session.toggleOverwrite();
+    }
+
+    /**
+     * Sets how fast the mouse scrolling should do.
+     * @param {Number} speed A value indicating the new speed (in milliseconds)
+     **/
+    setScrollSpeed(speed) {
+        this.setOption("scrollSpeed", speed);
+    }
+
+    /**
+     * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).
+     * @returns {Number}
+     **/
+    getScrollSpeed() {
+        return this.getOption("scrollSpeed");
+    }
+
+    /**
+     * Sets the delay (in milliseconds) of the mouse drag.
+     * @param {Number} dragDelay A value indicating the new delay
+     **/
+    setDragDelay(dragDelay) {
+        this.setOption("dragDelay", dragDelay);
+    }
+
+    /**
+     * Returns the current mouse drag delay.
+     * @returns {Number}
+     **/
+    getDragDelay() {
+        return this.getOption("dragDelay");
+    }
+
+
+    /**
+     * Draw selection markers spanning whole line, or only over selected text. Default value is "line"
+     * @param {"fullLine" | "screenLine" | "text" | "line"} val The new selection style "line"|"text"
+     **/
+    setSelectionStyle(val) {
+        this.setOption("selectionStyle", val);
+    }
+
+    /**
+     * Returns the current selection style.
+     * @returns {import("../ace-internal").Ace.EditorOptions["selectionStyle"]}
+     **/
+    getSelectionStyle() {
+        return this.getOption("selectionStyle");
+    }
+
+    /**
+     * Determines whether or not the current line should be highlighted.
+     * @param {Boolean} shouldHighlight Set to `true` to highlight the current line
+     **/
+    setHighlightActiveLine(shouldHighlight) {
+        this.setOption("highlightActiveLine", shouldHighlight);
+    }
+    /**
+     * Returns `true` if current lines are always highlighted.
+     * @return {Boolean}
+     **/
+    getHighlightActiveLine() {
+        return this.getOption("highlightActiveLine");
+    }
+
+    /**
+     * @param {boolean} shouldHighlight
+     */
+    setHighlightGutterLine(shouldHighlight) {
+        this.setOption("highlightGutterLine", shouldHighlight);
+    }
+
+    /**
+     * @returns {Boolean}
+     */
+    getHighlightGutterLine() {
+        return this.getOption("highlightGutterLine");
+    }
+
+    /**
+     * Determines if the currently selected word should be highlighted.
+     * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word
+     **/
+    setHighlightSelectedWord(shouldHighlight) {
+        this.setOption("highlightSelectedWord", shouldHighlight);
+    }
+
+    /**
+     * Returns `true` if currently highlighted words are to be highlighted.
+     * @returns {Boolean}
+     **/
+    getHighlightSelectedWord() {
+        return this.$highlightSelectedWord;
+    }
+
+    /**
+     * @param {boolean} shouldAnimate
+     */
+    setAnimatedScroll(shouldAnimate){
+        this.renderer.setAnimatedScroll(shouldAnimate);
+    }
+
+    /**
+     * @return {boolean}
+     */
+    getAnimatedScroll(){
+        return this.renderer.getAnimatedScroll();
+    }
+
+    /**
+     * If `showInvisibles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor.
+     * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters
+     **/
+    setShowInvisibles(showInvisibles) {
+        this.renderer.setShowInvisibles(showInvisibles);
+    }
+
+    /**
+     * Returns `true` if invisible characters are being shown.
+     * @returns {Boolean}
+     **/
+    getShowInvisibles() {
+        return this.renderer.getShowInvisibles();
+    }
+
+    /**
+     * @param {boolean} display
+     */
+    setDisplayIndentGuides(display) {
+        this.renderer.setDisplayIndentGuides(display);
+    }
+
+    /**
+     * @return {boolean}
+     */
+    getDisplayIndentGuides() {
+        return this.renderer.getDisplayIndentGuides();
+    }
+
+    /**
+     * @param {boolean} highlight
+     */
+    setHighlightIndentGuides(highlight) {
+        this.renderer.setHighlightIndentGuides(highlight);
+    }
+
+    /**
+     * @return {boolean}
+     */
+    getHighlightIndentGuides() {
+        return this.renderer.getHighlightIndentGuides();
+    }
+
+    /**
+     * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.
+     * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin
+     *
+     **/
+    setShowPrintMargin(showPrintMargin) {
+        this.renderer.setShowPrintMargin(showPrintMargin);
+    }
+
+    /**
+     * Returns `true` if the print margin is being shown.
+     * @returns {Boolean}
+     **/
+    getShowPrintMargin() {
+        return this.renderer.getShowPrintMargin();
+    }
+
+    /**
+     * Sets the column defining where the print margin should be.
+     * @param {Number} showPrintMargin Specifies the new print margin
+     *
+     **/
+    setPrintMarginColumn(showPrintMargin) {
+        this.renderer.setPrintMarginColumn(showPrintMargin);
+    }
+
+    /**
+     * Returns the column number of where the print margin is.
+     * @returns {Number}
+     **/
+    getPrintMarginColumn() {
+        return this.renderer.getPrintMarginColumn();
+    }
+
+    /**
+     * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.
+     * @param {Boolean} readOnly Specifies whether the editor can be modified or not
+     **/
+    setReadOnly(readOnly) {
+        this.setOption("readOnly", readOnly);
+    }
+
+    /**
+     * Returns `true` if the editor is set to read-only mode.
+     * @returns {Boolean}
+     **/
+    getReadOnly() {
+        return this.getOption("readOnly");
+    }
+
+    /**
+     * 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}
+     * @param {Boolean} enabled Enables or disables behaviors
+     **/
+    setBehavioursEnabled(enabled) {
+        this.setOption("behavioursEnabled", enabled);
+    }
+
+    /**
+     * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}
+     * @returns {Boolean}
+     **/
+    getBehavioursEnabled() {
+        return this.getOption("behavioursEnabled");
+    }
+
+    /**
+     * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets
+     * when such a character is typed in.
+     * @param {Boolean} enabled Enables or disables wrapping behaviors
+     **/
+    setWrapBehavioursEnabled(enabled) {
+        this.setOption("wrapBehavioursEnabled", enabled);
+    }
+
+    /**
+     * Returns `true` if the wrapping behaviors are currently enabled.
+     * @returns {boolean}
+     **/
+    getWrapBehavioursEnabled() {
+        return this.getOption("wrapBehavioursEnabled");
+    }
+
+    /**
+     * Indicates whether the fold widgets should be shown or not.
+     * @param {Boolean} show Specifies whether the fold widgets are shown
+     **/
+    setShowFoldWidgets(show) {
+        this.setOption("showFoldWidgets", show);
+
+    }
+    /**
+     * Returns `true` if the fold widgets are shown.
+     * @return {Boolean}
+     **/
+    getShowFoldWidgets() {
+        return this.getOption("showFoldWidgets");
+    }
+
+    /**
+     * @param {boolean} fade
+     */
+    setFadeFoldWidgets(fade) {
+        this.setOption("fadeFoldWidgets", fade);
+    }
+
+    /**
+     * @returns {boolean}
+     */
+    getFadeFoldWidgets() {
+        return this.getOption("fadeFoldWidgets");
+    }
+
+    /**
+     * Removes the current selection or one character.
+     * @param {'left' | 'right'} [dir] The direction of the deletion to occur, either "left" or "right"
+     **/
+    remove(dir) {
+        if (this.selection.isEmpty()){
+            if (dir == "left")
+                this.selection.selectLeft();
+            else
+                this.selection.selectRight();
+        }
+
+        var range = this.getSelectionRange();
+        if (this.getBehavioursEnabled()) {
+            var session = this.session;
+            var state = session.getState(range.start.row);
+            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
+
+            if (range.end.column === 0) {
+                var text = session.getTextRange(range);
+                if (text[text.length - 1] == "\n") {
+                    var line = session.getLine(range.end.row);
+                    if (/^\s+$/.test(line)) {
+                        range.end.column = line.length;
+                    }
+                }
+            }
+            if (new_range)
+                // @ts-expect-error TODO: possible bug, new_range could be not a Range
+                range = new_range;
+        }
+
+        this.session.remove(range);
+        this.clearSelection();
+    }
+
+    /**
+     * Removes the word directly to the right of the current selection.
+     **/
+    removeWordRight() {
+        if (this.selection.isEmpty())
+            this.selection.selectWordRight();
+
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    }
+
+    /**
+     * Removes the word directly to the left of the current selection.
+     **/
+    removeWordLeft() {
+        if (this.selection.isEmpty())
+            this.selection.selectWordLeft();
+
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    }
+
+    /**
+     * Removes all the words to the left of the current selection, until the start of the line.
+     **/
+    removeToLineStart() {
+        if (this.selection.isEmpty())
+            this.selection.selectLineStart();
+        if (this.selection.isEmpty())
+            this.selection.selectLeft();
+        this.session.remove(this.getSelectionRange());
+        this.clearSelection();
+    }
+
+    /**
+     * Removes all the words to the right of the current selection, until the end of the line.
+     **/
+    removeToLineEnd() {
+        if (this.selection.isEmpty())
+            this.selection.selectLineEnd();
+
+        var range = this.getSelectionRange();
+        if (range.start.column == range.end.column && range.start.row == range.end.row) {
+            range.end.column = 0;
+            range.end.row++;
+        }
+
+        this.session.remove(range);
+        this.clearSelection();
+    }
+
+    /**
+     * Splits the line at the current selection (by inserting an `'\n'`).
+     **/
+    splitLine() {
+        if (!this.selection.isEmpty()) {
+            this.session.remove(this.getSelectionRange());
+            this.clearSelection();
+        }
+
+        var cursor = this.getCursorPosition();
+        this.insert("\n");
+        this.moveCursorToPosition(cursor);
+    }
+
+    /**
+     * Set the "ghost" text in provided position. "Ghost" text is a kind of
+     * preview text inside the editor which can be used to preview some code
+     * inline in the editor such as, for example, code completions.
+     *
+     * @param {String} text Text to be inserted as "ghost" text
+     * @param {Point} [position] Position to insert text to
+     */
+    setGhostText(text, position) {
+        this.renderer.setGhostText(text, position);
+    }
+
+    /**
+     * Removes "ghost" text currently displayed in the editor.
+     */
+    removeGhostText() {
+        this.renderer.removeGhostText();
+    }
+
+    /**
+     * Transposes current line.
+     **/
+    transposeLetters() {
+        if (!this.selection.isEmpty()) {
+            return;
+        }
+
+        var cursor = this.getCursorPosition();
+        var column = cursor.column;
+        if (column === 0)
+            return;
+
+        var line = this.session.getLine(cursor.row);
+        var swap, range;
+        if (column < line.length) {
+            swap = line.charAt(column) + line.charAt(column-1);
+            range = new Range(cursor.row, column-1, cursor.row, column+1);
+        }
+        else {
+            swap = line.charAt(column-1) + line.charAt(column-2);
+            range = new Range(cursor.row, column-2, cursor.row, column);
+        }
+        this.session.replace(range, swap);
+        this.session.selection.moveToPosition(range.end);
+    }
+
+    /**
+     * Converts the current selection entirely into lowercase.
+     **/
+    toLowerCase() {
+        var originalRange = this.getSelectionRange();
+        if (this.selection.isEmpty()) {
+            this.selection.selectWord();
+        }
+
+        var range = this.getSelectionRange();
+        var text = this.session.getTextRange(range);
+        this.session.replace(range, text.toLowerCase());
+        this.selection.setSelectionRange(originalRange);
+    }
+
+    /**
+     * Converts the current selection entirely into uppercase.
+     **/
+    toUpperCase() {
+        var originalRange = this.getSelectionRange();
+        if (this.selection.isEmpty()) {
+            this.selection.selectWord();
+        }
+
+        var range = this.getSelectionRange();
+        var text = this.session.getTextRange(range);
+        this.session.replace(range, text.toUpperCase());
+        this.selection.setSelectionRange(originalRange);
+    }
+
+    /**
+     * Inserts an indentation into the current cursor position or indents the selected lines.
+     *
+     * @related EditSession.indentRows
+     **/
+    indent() {
+        var session = this.session;
+        var range = this.getSelectionRange();
+
+        if (range.start.row < range.end.row) {
+            var rows = this.$getSelectedRows();
+            session.indentRows(rows.first, rows.last, "\t");
+            return;
+        } else if (range.start.column < range.end.column) {
+            var text = session.getTextRange(range);
+            if (!/^\s+$/.test(text)) {
+                var rows = this.$getSelectedRows();
+                session.indentRows(rows.first, rows.last, "\t");
+                return;
+            }
+        }
+
+        var line = session.getLine(range.start.row);
+        var position = range.start;
+        var size = session.getTabSize();
+        var column = session.documentToScreenColumn(position.row, position.column);
+
+        if (this.session.getUseSoftTabs()) {
+            var count = (size - column % size);
+            var indentString = lang.stringRepeat(" ", count);
+        } else {
+            var count = column % size;
+            while (line[range.start.column - 1] == " " && count) {
+                range.start.column--;
+                count--;
+            }
+            this.selection.setSelectionRange(range);
+            indentString = "\t";
+        }
+        return this.insert(indentString);
+    }
+
+    /**
+     * Indents the current line.
+     * @related EditSession.indentRows
+     **/
+    blockIndent() {
+        var rows = this.$getSelectedRows();
+        this.session.indentRows(rows.first, rows.last, "\t");
+    }
+
+    /**
+     * Outdents the current line.
+     * @related EditSession.outdentRows
+     **/
+    blockOutdent() {
+        var selection = this.session.getSelection();
+        this.session.outdentRows(selection.getRange());
+    }
+
+    // TODO: move out of core when we have good mechanism for managing extensions
+    sortLines() {
+        var rows = this.$getSelectedRows();
+        var session = this.session;
+
+        var lines = [];
+        for (var i = rows.first; i <= rows.last; i++)
+            lines.push(session.getLine(i));
+
+        lines.sort(function(a, b) {
+            if (a.toLowerCase() < b.toLowerCase()) return -1;
+            if (a.toLowerCase() > b.toLowerCase()) return 1;
+            return 0;
+        });
+
+        var deleteRange = new Range(0, 0, 0, 0);
+        for (var i = rows.first; i <= rows.last; i++) {
+            var line = session.getLine(i);
+            deleteRange.start.row = i;
+            deleteRange.end.row = i;
+            deleteRange.end.column = line.length;
+            session.replace(deleteRange, lines[i-rows.first]);
+        }
+    }
+
+    /**
+     * Given the currently selected range, this function either comments all the lines, or uncomments all of them.
+     **/
+    toggleCommentLines() {
+        var state = this.session.getState(this.getCursorPosition().row);
+        var rows = this.$getSelectedRows();
+        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
+    }
+
+    toggleBlockComment() {
+        var cursor = this.getCursorPosition();
+        var state = this.session.getState(cursor.row);
+        var range = this.getSelectionRange();
+        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);
+    }
+
+    /**
+     * Works like [[EditSession.getTokenAt]], except it returns a number.
+     * @returns {any}
+     **/
+    getNumberAt(row, column) {
+        var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g;
+        _numberRx.lastIndex = 0;
+
+        var s = this.session.getLine(row);
+        while (_numberRx.lastIndex < column) {
+            var m = _numberRx.exec(s);
+            if(m.index <= column && m.index+m[0].length >= column){
+                var number = {
+                    value: m[0],
+                    start: m.index,
+                    end: m.index+m[0].length
+                };
+                return number;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * If the character before the cursor is a number, this functions changes its value by `amount`.
+     * @param {Number} amount The value to change the numeral by (can be negative to decrease value)
+     **/
+    modifyNumber(amount) {
+        var row = this.selection.getCursor().row;
+        var column = this.selection.getCursor().column;
+
+        // get the char before the cursor
+        var charRange = new Range(row, column-1, row, column);
+
+        var c = this.session.getTextRange(charRange);
+        // if the char is a digit
+        // @ts-ignore
+        if (!isNaN(parseFloat(c)) && isFinite(c)) {
+            // get the whole number the digit is part of
+            var nr = this.getNumberAt(row, column);
+            // if number found
+            if (nr) {
+                var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
+                var decimals = nr.start + nr.value.length - fp;
+
+                var t = parseFloat(nr.value);
+                t *= Math.pow(10, decimals);
+
+
+                if(fp !== nr.end && column < fp){
+                    amount *= Math.pow(10, nr.end - column - 1);
+                } else {
+                    amount *= Math.pow(10, nr.end - column);
+                }
+
+                t += amount;
+                t /= Math.pow(10, decimals);
+                var nnr = t.toFixed(decimals);
+
+                //update number
+                var replaceRange = new Range(row, nr.start, row, nr.end);
+                this.session.replace(replaceRange, nnr);
+
+                //reposition the cursor
+                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
+
+            }
+        } else {
+            this.toggleWord();
+        }
+    }
+
+    /**
+     */
+    toggleWord() {
+        var row = this.selection.getCursor().row;
+        var column = this.selection.getCursor().column;
+        this.selection.selectWord();
+        var currentState = this.getSelectedText();
+        var currWordStart = this.selection.getWordRange().start.column;
+        var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\s/);
+        var delta = column - currWordStart - 1;
+        if (delta < 0) delta = 0;
+        var curLength = 0, itLength = 0;
+        var that = this;
+        if (currentState.match(/[A-Za-z0-9_]+/)) {
+            wordParts.forEach(function (item, i) {
+                itLength = curLength + item.length;
+                if (delta >= curLength && delta <= itLength) {
+                    currentState = item;
+                    that.selection.clearSelection();
+                    that.moveCursorTo(row, curLength + currWordStart);
+                    that.selection.selectTo(row, itLength + currWordStart);
+                }
+                curLength = itLength;
+            });
+        }
+
+        var wordPairs = this.$toggleWordPairs;
+        var reg;
+        for (var i = 0; i < wordPairs.length; i++) {
+            var item = wordPairs[i];
+            for (var j = 0; j <= 1; j++) {
+                var negate = +!j;
+                var firstCondition = currentState.match(new RegExp('^\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\s?$', 'i'));
+                if (firstCondition) {
+                    var secondCondition = currentState.match(new RegExp('([_]|^|\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\s)', 'g'));
+                    if (secondCondition) {
+                        reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) {
+                            var res = item[negate];
+                            if (result.toUpperCase() == result) {
+                                res = res.toUpperCase();
+                            } else if (result.charAt(0).toUpperCase() == result.charAt(0)) {
+                                res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1);
+                            }
+                            return res;
+                        });
+                        this.insert(reg);
+                        reg = "";
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Finds link at defined {row} and {column}
+     * @returns {String}
+     **/
+    findLinkAt(row, column) {
+        var line = this.session.getLine(row);
+        var wordParts = line.split(/((?:https?|ftp):\/\/[\S]+)/);
+        var columnPosition = column;
+        if (columnPosition < 0) columnPosition = 0;
+        var previousPosition = 0, currentPosition = 0, match;
+        for (let item of wordParts) {
+            currentPosition = previousPosition + item.length;
+            if (columnPosition >= previousPosition && columnPosition <= currentPosition) {
+                if (item.match(/((?:https?|ftp):\/\/[\S]+)/)) {
+                    match = item.replace(/[\s:.,'";}\]]+$/, "");
+                    break;
+                }
+            }
+            previousPosition = currentPosition;
+        }
+        return match;
+    }
+
+    /**
+     * Open valid url under cursor in another tab
+     * @returns {Boolean}
+     **/
+    openLink() {
+        var cursor =  this.selection.getCursor();
+        var url = this.findLinkAt(cursor.row, cursor.column);
+        if (url)
+            window.open(url, '_blank');
+        return url != null;
+    }
+
+    /**
+     * Removes all the lines in the current selection
+     * @related EditSession.remove
+     **/
+    removeLines() {
+        var rows = this.$getSelectedRows();
+        this.session.removeFullLines(rows.first, rows.last);
+        this.clearSelection();
+    }
+
+    duplicateSelection() {
+        var sel = this.selection;
+        var doc = this.session;
+        var range = sel.getRange();
+        var reverse = sel.isBackwards();
+        if (range.isEmpty()) {
+            var row = range.start.row;
+            doc.duplicateLines(row, row);
+        } else {
+            var point = reverse ? range.start : range.end;
+            var endPoint = doc.insert(point, doc.getTextRange(range));
+            range.start = point;
+            range.end = endPoint;
+
+            sel.setSelectionRange(range, reverse);
+        }
+    }
+
+    /**
+     * Shifts all the selected lines down one row.
+     *
+     * @related EditSession.moveLinesUp
+     **/
+    moveLinesDown() {
+        this.$moveLines(1, false);
+    }
+
+    /**
+     * Shifts all the selected lines up one row.
+     * @related EditSession.moveLinesDown
+     **/
+    moveLinesUp() {
+        this.$moveLines(-1, false);
+    }
+
+    /**
+     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:
+     * ```json
+     *    { row: newRowLocation, column: newColumnLocation }
+     * ```
+     * @param {Range} range The range of text you want moved within the document
+     * @param {Point} toPosition The location (row and column) where you want to move the text to
+     * @param {boolean} [copy]
+     *
+     * @returns {Range} The new range where the text was moved to.
+     * @related EditSession.moveText
+     **/
+    moveText(range, toPosition, copy) {
+        return this.session.moveText(range, toPosition, copy);
+    }
+
+    /**
+     * Copies all the selected lines up one row.
+     *
+     **/
+   copyLinesUp() {
+        this.$moveLines(-1, true);
+    }
+
+    /**
+     * Copies all the selected lines down one row.
+     * @related EditSession.duplicateLines
+     *
+     **/
+    copyLinesDown() {
+        this.$moveLines(1, true);
+    }
+
+    /**
+     * for internal use
+     * @ignore
+     *
+     **/
+    $moveLines(dir, copy) {
+        var rows, moved;
+        var selection = this.selection;
+        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
+            var range = selection.toOrientedRange();
+            rows = this.$getSelectedRows(range);
+            moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);
+            if (copy && dir == -1) moved = 0;
+            range.moveBy(moved, 0);
+            selection.fromOrientedRange(range);
+        } else {
+            var ranges = selection.rangeList.ranges;
+            // @ts-expect-error TODO: possible bug, no args in parameters
+            selection.rangeList.detach(this.session);
+            this.inVirtualSelectionMode = true;
+
+            var diff = 0;
+            var totalDiff = 0;
+            var l = ranges.length;
+            for (var i = 0; i < l; i++) {
+                var rangeIndex = i;
+                ranges[i].moveBy(diff, 0);
+                rows = this.$getSelectedRows(ranges[i]);
+                var first = rows.first;
+                var last = rows.last;
+                while (++i < l) {
+                    if (totalDiff) ranges[i].moveBy(totalDiff, 0);
+                    var subRows = this.$getSelectedRows(ranges[i]);
+                    if (copy && subRows.first != last)
+                        break;
+                    else if (!copy && subRows.first > last + 1)
+                        break;
+                    last = subRows.last;
+                }
+                i--;
+                diff = this.session.$moveLines(first, last, copy ? 0 : dir);
+                if (copy && dir == -1) rangeIndex = i + 1;
+                while (rangeIndex <= i) {
+                    ranges[rangeIndex].moveBy(diff, 0);
+                    rangeIndex++;
+                }
+                if (!copy) diff = 0;
+                totalDiff += diff;
+            }
+
+            selection.fromOrientedRange(selection.ranges[0]);
+            selection.rangeList.attach(this.session);
+            this.inVirtualSelectionMode = false;
+        }
+    }
+
+    /**
+     * Returns an object indicating the currently selected rows. The object looks like this:
+     *
+     * ```json
+     * { first: range.start.row, last: range.end.row }
+     * ```
+     *
+     * @returns {Object}
+     **/
+    $getSelectedRows(range) {
+        range = (range || this.getSelectionRange()).collapseRows();
+
+        return {
+            first: this.session.getRowFoldStart(range.start.row),
+            last: this.session.getRowFoldEnd(range.end.row)
+        };
+    }
+
+    /**
+     * @internal
+     */
+    onCompositionStart(compositionState) {
+        this.renderer.showComposition(compositionState);
+    }
+
+    /**
+     * @internal
+     */
+    onCompositionUpdate(text) {
+        this.renderer.setCompositionText(text);
+    }
+
+    /**
+     * @internal
+     */
+    onCompositionEnd() {
+        this.renderer.hideComposition();
+    }
+
+    /**
+     * {:VirtualRenderer.getFirstVisibleRow}
+     *
+     * @returns {Number}
+     * @related VirtualRenderer.getFirstVisibleRow
+     **/
+    getFirstVisibleRow() {
+        return this.renderer.getFirstVisibleRow();
+    }
+
+    /**
+     * {:VirtualRenderer.getLastVisibleRow}
+     *
+     * @returns {Number}
+     * @related VirtualRenderer.getLastVisibleRow
+     **/
+    getLastVisibleRow() {
+        return this.renderer.getLastVisibleRow();
+    }
+
+    /**
+     * Indicates if the row is currently visible on the screen.
+     * @param {Number} row The row to check
+     *
+     * @returns {Boolean}
+     **/
+    isRowVisible(row) {
+        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
+    }
+
+    /**
+     * Indicates if the entire row is currently visible on the screen.
+     * @param {Number} row The row to check
+     *
+     *
+     * @returns {Boolean}
+     **/
+    isRowFullyVisible(row) {
+        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
+    }
+
+    /**
+     * Returns the number of currently visible rows.
+     * @returns {Number}
+     **/
+    $getVisibleRowCount() {
+        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
+    }
+
+    $moveByPage(dir, select) {
+        var renderer = this.renderer;
+        var config = this.renderer.layerConfig;
+        var rows = dir * Math.floor(config.height / config.lineHeight);
+
+        if (select === true) {
+            this.selection.$moveSelection(function(){
+                this.moveCursorBy(rows, 0);
+            });
+        } else if (select === false) {
+            this.selection.moveCursorBy(rows, 0);
+            this.selection.clearSelection();
+        }
+
+        var scrollTop = renderer.scrollTop;
+
+        renderer.scrollBy(0, rows * config.lineHeight);
+        if (select != null)
+            renderer.scrollCursorIntoView(null, 0.5);
+
+        renderer.animateScrolling(scrollTop);
+    }
+
+    /**
+     * Selects the text from the current position of the document until where a "page down" finishes.
+     **/
+    selectPageDown() {
+        this.$moveByPage(1, true);
+    }
+
+    /**
+     * Selects the text from the current position of the document until where a "page up" finishes.
+     **/
+    selectPageUp() {
+        this.$moveByPage(-1, true);
+    }
+
+    /**
+     * Shifts the document to wherever "page down" is, as well as moving the cursor position.
+     **/
+    gotoPageDown() {
+       this.$moveByPage(1, false);
+    }
+
+    /**
+     * Shifts the document to wherever "page up" is, as well as moving the cursor position.
+     **/
+    gotoPageUp() {
+        this.$moveByPage(-1, false);
+    }
+
+    /**
+     * Scrolls the document to wherever "page down" is, without changing the cursor position.
+     **/
+    scrollPageDown() {
+        this.$moveByPage(1);
+    }
+
+    /**
+     * Scrolls the document to wherever "page up" is, without changing the cursor position.
+     **/
+    scrollPageUp() {
+        this.$moveByPage(-1);
+    }
+
+    /**
+     * Moves the editor to the specified row.
+     * @related VirtualRenderer.scrollToRow
+     * @param {number} row
+     */
+    scrollToRow(row) {
+        this.renderer.scrollToRow(row);
+    }
+
+    /**
+     * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).
+     * @param {Number} line The line to scroll to
+     * @param {Boolean} center If `true`
+     * @param {Boolean} animate If `true` animates scrolling
+     * @param {() => void} [callback] Function to be called when the animation has finished
+     *
+     * @related VirtualRenderer.scrollToLine
+     **/
+    scrollToLine(line, center, animate, callback) {
+        this.renderer.scrollToLine(line, center, animate, callback);
+    }
+
+    /**
+     * Attempts to center the current selection on the screen.
+     **/
+    centerSelection() {
+        var range = this.getSelectionRange();
+        var pos = {
+            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
+            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
+        };
+        this.renderer.alignCursor(pos, 0.5);
+    }
+
+    /**
+     * Gets the current position of the cursor.
+     * @returns {Point} An object that looks something like this:
+     *
+     * ```json
+     * { row: currRow, column: currCol }
+     * ```
+     *
+     * @related Selection.getCursor
+     **/
+    getCursorPosition() {
+        return this.selection.getCursor();
+    }
+
+    /**
+     * Returns the screen position of the cursor.
+     * @returns {Point}
+     * @related EditSession.documentToScreenPosition
+     **/
+    getCursorPositionScreen() {
+        return this.session.documentToScreenPosition(this.getCursorPosition());
+    }
+
+    /**
+     * {:Selection.getRange}
+     * @returns {Range}
+     * @related Selection.getRange
+     **/
+    getSelectionRange() {
+        return this.selection.getRange();
+    }
+
+    /**
+     * Selects all the text in editor.
+     * @related Selection.selectAll
+     **/
+    selectAll() {
+        this.selection.selectAll();
+    }
+
+    /**
+     * {:Selection.clearSelection}
+     * @related Selection.clearSelection
+     **/
+    clearSelection() {
+        this.selection.clearSelection();
+    }
+
+    /**
+     * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.
+     * @param {Number} row The new row number
+     * @param {Number} column The new column number
+     * @related Selection.moveCursorTo
+     **/
+    moveCursorTo(row, column) {
+        this.selection.moveCursorTo(row, column);
+    }
+
+    /**
+     * Moves the cursor to the position indicated by `pos.row` and `pos.column`.
+     * @param {Point} pos An object with two properties, row and column
+     * @related Selection.moveCursorToPosition
+     **/
+    moveCursorToPosition(pos) {
+        this.selection.moveCursorToPosition(pos);
+    }
+
+    /**
+     * Moves the cursor's row and column to the next matching bracket or HTML tag.
+     * @param {boolean} [select]
+     * @param {boolean} [expand]
+     */
+    jumpToMatching(select, expand) {
+        var cursor = this.getCursorPosition();
+        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
+        var prevToken = iterator.getCurrentToken();
+        var tokenCount = 0;
+        if (prevToken && prevToken.type.indexOf('tag-name') !== -1) {
+            prevToken = iterator.stepBackward();
+        }
+        var token = prevToken || iterator.stepForward();
+
+        if (!token) return;
+
+        //get next closing tag or bracket
+        var matchType;
+        var found = false;
+        var depth = {};
+        var i = cursor.column - token.start;
+        var bracketType;
+        var brackets = {
+            ")": "(",
+            "(": "(",
+            "]": "[",
+            "[": "[",
+            "{": "{",
+            "}": "{"
+        };
+
+        do {
+            if (token.value.match(/[{}()\[\]]/g)) {
+                for (; i < token.value.length && !found; i++) {
+                    if (!brackets[token.value[i]]) {
+                        continue;
+                    }
+
+                    bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
+
+                    if (isNaN(depth[bracketType])) {
+                        depth[bracketType] = 0;
+                    }
+
+                    switch (token.value[i]) {
+                        case '(':
+                        case '[':
+                        case '{':
+                            depth[bracketType]++;
+                            break;
+                        case ')':
+                        case ']':
+                        case '}':
+                            depth[bracketType]--;
+
+                            if (depth[bracketType] === -1) {
+                                matchType = 'bracket';
+                                found = true;
+                            }
+                            break;
+                    }
+                }
+            }
+            else if (token.type.indexOf('tag-name') !== -1) {
+                if (isNaN(depth[token.value])) {
+                    depth[token.value] = 0;
+                }
+
+                if (prevToken.value === '<' && tokenCount > 1) {
+                    depth[token.value]++;
+                }
+                else if (prevToken.value === '} [options] The [[Search `Search`]] options to use
+     * @return {number}
+     **/
+    replace(replacement, options) {
+        if (options)
+            this.$search.set(options);
+
+        var range = this.$search.find(this.session);
+        var replaced = 0;
+        if (!range)
+            return replaced;
+
+        if (this.$tryReplace(range, replacement)) {
+            replaced = 1;
+        }
+
+        this.selection.setSelectionRange(range);
+        this.renderer.scrollSelectionIntoView(range.start, range.end);
+
+        return replaced;
+    }
+
+    /**
+     * Replaces all occurrences of `options.needle` with the value in `replacement`.
+     * @param {String} [replacement] The text to replace with
+     * @param {Partial} [options] The [[Search `Search`]] options to use
+     * @return {number}
+     **/
+    replaceAll(replacement, options) {
+        if (options) {
+            this.$search.set(options);
+        }
+
+        var ranges = this.$search.findAll(this.session);
+        var replaced = 0;
+        if (!ranges.length)
+            return replaced;
+
+        var selection = this.getSelectionRange();
+        this.selection.moveTo(0, 0);
+
+        for (var i = ranges.length - 1; i >= 0; --i) {
+            if(this.$tryReplace(ranges[i], replacement)) {
+                replaced++;
+            }
+        }
+
+        this.selection.setSelectionRange(selection);
+
+        return replaced;
+    }
+
+    /**
+     * @param {import("../ace-internal").Ace.IRange} range
+     * @param {string} [replacement]
+     */
+    $tryReplace(range, replacement) {
+        var input = this.session.getTextRange(range);
+        replacement = this.$search.replace(input, replacement);
+        if (replacement !== null) {
+            range.end = this.session.replace(range, replacement);
+            return range;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].
+     * @related Search.getOptions
+     * @returns {Partial}
+     **/
+    getLastSearchOptions() {
+        return this.$search.getOptions();
+    }
+
+    /**
+     * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].
+     * @param {String|RegExp|Object} needle The text to search for (optional)
+     * @param {Partial} [options] An object defining various search properties
+     * @param {Boolean} [animate] If `true` animate scrolling
+     * @related Search.find
+     **/
+    find(needle, options, animate) {
+        if (!options)
+            options = {};
+
+        if (typeof needle == "string" || needle instanceof RegExp)
+            options.needle = needle;
+        else if (typeof needle == "object")
+            oop.mixin(options, needle);
+
+        var range = this.selection.getRange();
+        if (options.needle == null) {
+            needle = this.session.getTextRange(range)
+                || this.$search.$options.needle;
+            if (!needle) {
+                range = this.session.getWordRange(range.start.row, range.start.column);
+                needle = this.session.getTextRange(range);
+            }
+            this.$search.set({needle: needle});
+        }
+
+        this.$search.set(options);
+        if (!options.start)
+            this.$search.set({start: range});
+
+        var newRange = this.$search.find(this.session);
+        if (options.preventScroll)
+            return newRange;
+        if (newRange) {
+            this.revealRange(newRange, animate);
+            return newRange;
+        }
+        // clear selection if nothing is found
+        if (options.backwards)
+            range.start = range.end;
+        else
+            range.end = range.start;
+        this.selection.setRange(range);
+    }
+
+    /**
+     * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].
+     * @param {Partial} [options] search options
+     * @param {Boolean} [animate] If `true` animate scrolling
+     *
+     * @related Editor.find
+     **/
+    findNext(options, animate) {
+        this.find({skipCurrent: true, backwards: false}, options, animate);
+    }
+
+    /**
+     * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].
+     * @param {Partial} [options] search options
+     * @param {Boolean} [animate] If `true` animate scrolling
+     *
+     * @related Editor.find
+     **/
+    findPrevious(options, animate) {
+        this.find(options, {skipCurrent: true, backwards: true}, animate);
+    }
+
+    /**
+     *
+     * @param {Range} range
+     * @param {boolean} [animate]
+     */
+    revealRange(range, animate) {
+        this.session.unfold(range);
+        this.selection.setSelectionRange(range);
+
+        var scrollTop = this.renderer.scrollTop;
+        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
+        if (animate !== false)
+            this.renderer.animateScrolling(scrollTop);
+    }
+
+    /**
+     * {:UndoManager.undo}
+     * @related UndoManager.undo
+     **/
+    undo() {
+        this.session.getUndoManager().undo(this.session);
+        this.renderer.scrollCursorIntoView(null, 0.5);
+    }
+
+    /**
+     * {:UndoManager.redo}
+     * @related UndoManager.redo
+     **/
+    redo() {
+        this.session.getUndoManager().redo(this.session);
+        this.renderer.scrollCursorIntoView(null, 0.5);
+    }
+
+    /**
+     *
+     * Cleans up the entire editor.
+     **/
+    destroy() {
+        if (this.$toDestroy) {
+            this.$toDestroy.forEach(function(el) {
+                el.destroy();
+            });
+            this.$toDestroy = null;
+        }
+        if (this.$mouseHandler)
+            this.$mouseHandler.destroy();
+        this.renderer.destroy();
+        this._signal("destroy", this);
+        if (this.session)
+            this.session.destroy();
+        if (this._$emitInputEvent)
+            this._$emitInputEvent.cancel();
+        this.removeAllListeners();
+
+    }
+
+    /**
+     * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element
+     * @param {Boolean} enable default true
+     **/
+    setAutoScrollEditorIntoView(enable) {
+        if (!enable)
+            return;
+        var rect;
+        var self = this;
+        var shouldScroll = false;
+        if (!this.$scrollAnchor)
+            this.$scrollAnchor = document.createElement("div");
+        var scrollAnchor = this.$scrollAnchor;
+        scrollAnchor.style.cssText = "position:absolute";
+        this.container.insertBefore(scrollAnchor, this.container.firstChild);
+        var onChangeSelection = this.on("changeSelection", function() {
+            shouldScroll = true;
+        });
+        // needed to not trigger sync reflow
+        var onBeforeRender = this.renderer.on("beforeRender", function() {
+            if (shouldScroll)
+                rect = self.renderer.container.getBoundingClientRect();
+        });
+        var onAfterRender = this.renderer.on("afterRender", function() {
+            if (shouldScroll && rect && (self.isFocused()
+                || self.searchBox && self.searchBox.isFocused())
+            ) {
+                var renderer = self.renderer;
+                var pos = renderer.$cursorLayer.$pixelPos;
+                var config = renderer.layerConfig;
+                var top = pos.top - config.offset;
+                if (pos.top >= 0 && top + rect.top < 0) {
+                    shouldScroll = true;
+                } else if (pos.top < config.height &&
+                    pos.top + rect.top + config.lineHeight > window.innerHeight) {
+                    shouldScroll = false;
+                } else {
+                    shouldScroll = null;
+                }
+                if (shouldScroll != null) {
+                    scrollAnchor.style.top = top + "px";
+                    scrollAnchor.style.left = pos.left + "px";
+                    scrollAnchor.style.height = config.lineHeight + "px";
+                    scrollAnchor.scrollIntoView(shouldScroll);
+                }
+                shouldScroll = rect = null;
+            }
+        });
+        this.setAutoScrollEditorIntoView = function(enable) {
+            if (enable)
+                return;
+            delete this.setAutoScrollEditorIntoView;
+            this.off("changeSelection", onChangeSelection);
+            this.renderer.off("afterRender", onAfterRender);
+            this.renderer.off("beforeRender", onBeforeRender);
+        };
+    }
+
+    $resetCursorStyle() {
+        var style = this.$cursorStyle || "ace";
+        var cursorLayer = this.renderer.$cursorLayer;
+        if (!cursorLayer)
+            return;
+        cursorLayer.setSmoothBlinking(/smooth/.test(style));
+        cursorLayer.isBlinking = !this.$readOnly && style != "wide";
+        dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style));
+    }
+
+    /**
+     * opens a prompt displaying message
+     **/
+    prompt(message, options, callback) {
+        var editor = this;
+        config.loadModule("ace/ext/prompt", function (module) {
+            module.prompt(editor, message, options, callback);
+        });
+    }
+
+}
+
+Editor.$uid = 0;
+Editor.prototype.curOp = null;
+Editor.prototype.prevOp = {};
+// TODO use property on commands instead of this
+Editor.prototype.$mergeableCommands = ["backspace", "del", "insertstring"];
+Editor.prototype.$toggleWordPairs = [
+    ["first", "last"],
+    ["true", "false"],
+    ["yes", "no"],
+    ["width", "height"],
+    ["top", "bottom"],
+    ["right", "left"],
+    ["on", "off"],
+    ["x", "y"],
+    ["get", "set"],
+    ["max", "min"],
+    ["horizontal", "vertical"],
+    ["show", "hide"],
+    ["add", "remove"],
+    ["up", "down"],
+    ["before", "after"],
+    ["even", "odd"],
+    ["in", "out"],
+    ["inside", "outside"],
+    ["next", "previous"],
+    ["increase", "decrease"],
+    ["attach", "detach"],
+    ["&&", "||"],
+    ["==", "!="]
+];
+
+oop.implement(Editor.prototype, EventEmitter);
+
+
+config.defineOptions(Editor.prototype, "editor", {
+    selectionStyle: {
+        set: function(style) {
+            this.onSelectionChange();
+            this._signal("changeSelectionStyle", {data: style});
+        },
+        initialValue: "line"
+    },
+    highlightActiveLine: {
+        set: function() {this.$updateHighlightActiveLine();},
+        initialValue: true
+    },
+    highlightSelectedWord: {
+        set: function(shouldHighlight) {this.$onSelectionChange();},
+        initialValue: true
+    },
+    readOnly: {
+        set: function(/**@type{boolean}*/readOnly) {
+            this.textInput.setReadOnly(readOnly);
+            this.$resetCursorStyle();
+            if (!this.$readOnlyCallback) {
+                this.$readOnlyCallback = (e) => {
+                    var shouldShow = false;
+                    if (e && e.type == "keydown") {
+                        shouldShow = e && e.key && e.key.length == 1 && !e.ctrlKey && !e.metaKey;
+                        if (!shouldShow) return;
+                    } else if (e && e.type !== "exec") {
+                        shouldShow = true;
+                    }
+                    if (shouldShow) {
+                        if (!this.hoverTooltip) {
+                            this.hoverTooltip = new HoverTooltip();
+                        }
+                        var domNode = dom.createElement("div");
+                        domNode.textContent = nls("editor.tooltip.disable-editing", "Editing is disabled");
+                        if (!this.hoverTooltip.isOpen) {
+                            this.hoverTooltip.showForRange(this, this.getSelectionRange(), domNode);
+                        }
+                    } else if (this.hoverTooltip && this.hoverTooltip.isOpen) {
+                        this.hoverTooltip.hide();
+                    }
+                };
+            }
+            var textArea = this.textInput.getElement();
+            if (readOnly) {
+                event.addListener(textArea, "keydown", this.$readOnlyCallback, this);
+                this.commands.on("exec", this.$readOnlyCallback);
+                this.commands.on("commandUnavailable", this.$readOnlyCallback);
+            } else {
+                event.removeListener(textArea, "keydown", this.$readOnlyCallback);
+                this.commands.off("exec", this.$readOnlyCallback);
+                this.commands.off("commandUnavailable", this.$readOnlyCallback);
+                if (this.hoverTooltip) {
+                    this.hoverTooltip.destroy();
+                    this.hoverTooltip = null;
+                }
+            }
+        },
+        initialValue: false
+    },
+    copyWithEmptySelection: {
+        set: function(value) {
+            this.textInput.setCopyWithEmptySelection(value);
+        },
+        initialValue: false
+    },
+    cursorStyle: {
+        set: function(val) { this.$resetCursorStyle(); },
+        values: ["ace", "slim", "smooth", "wide"],
+        initialValue: "ace"
+    },
+    mergeUndoDeltas: {
+        values: [false, true, "always"],
+        initialValue: true
+    },
+    behavioursEnabled: {initialValue: true},
+    wrapBehavioursEnabled: {initialValue: true},
+    enableAutoIndent: {initialValue: true},
+    autoScrollEditorIntoView: {
+        set: function(val) {this.setAutoScrollEditorIntoView(val);}
+    },
+    keyboardHandler: {
+        set: function(val) { this.setKeyboardHandler(val); },
+        get: function() { return this.$keybindingId; },
+        handlesSet: true
+    },
+    value: {
+        set: function(val) { this.session.setValue(val); },
+        get: function() { return this.getValue(); },
+        handlesSet: true,
+        hidden: true
+    },
+    session: {
+        set: function(val) { this.setSession(val); },
+        get: function() { return this.session; },
+        handlesSet: true,
+        hidden: true
+    },
+
+    showLineNumbers: {
+        set: function(show) {
+            this.renderer.$gutterLayer.setShowLineNumbers(show);
+            this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER);
+            if (show && this.$relativeLineNumbers)
+                relativeNumberRenderer.attach(this);
+            else
+                relativeNumberRenderer.detach(this);
+        },
+        initialValue: true
+    },
+    relativeLineNumbers: {
+        set: function(value) {
+            if (this.$showLineNumbers && value)
+                relativeNumberRenderer.attach(this);
+            else
+                relativeNumberRenderer.detach(this);
+        }
+    },
+    placeholder: {
+        /**
+         * @param message
+         */
+        set: function(message) {
+            if (!this.$updatePlaceholder) {
+                this.$updatePlaceholder = function() {
+                    var hasValue = this.session && (this.renderer.$composition ||
+                         this.session.getLength() > 1 || this.session.getLine(0).length > 0);
+                    if (hasValue && this.renderer.placeholderNode) {
+                        this.renderer.off("afterRender", this.$updatePlaceholder);
+                        dom.removeCssClass(this.container, "ace_hasPlaceholder");
+                        this.renderer.placeholderNode.remove();
+                        this.renderer.placeholderNode = null;
+                    } else if (!hasValue && !this.renderer.placeholderNode) {
+                        this.renderer.on("afterRender", this.$updatePlaceholder);
+                        dom.addCssClass(this.container, "ace_hasPlaceholder");
+                        var el = dom.createElement("div");
+                        el.className = "ace_placeholder";
+                        el.textContent = this.$placeholder || "";
+                        this.renderer.placeholderNode = el;
+                        this.renderer.content.appendChild(this.renderer.placeholderNode);
+                    } else if (!hasValue && this.renderer.placeholderNode) {
+                        this.renderer.placeholderNode.textContent = this.$placeholder || "";
+                    }
+                }.bind(this);
+                // @ts-ignore
+                this.on("input", this.$updatePlaceholder);
+            }
+            this.$updatePlaceholder();
+        }
+    },
+    enableKeyboardAccessibility: {
+        set: function(value) {
+            var blurCommand = {
+                name: "blurTextInput",
+                description: "Set focus to the editor content div to allow tabbing through the page",
+                bindKey: "Esc",
+                exec: function(editor) {
+                    editor.blur();
+                    editor.renderer.scroller.focus();
+                },
+                readOnly: true
+            };
+
+            var focusOnEnterKeyup = function (e) {
+                if (e.target == this.renderer.scroller && e.keyCode === keys['enter']){
+                    e.preventDefault();
+                    var row = this.getCursorPosition().row;
+
+                    if (!this.isRowVisible(row))
+                        this.scrollToLine(row, true, true);
+
+                    this.focus();
+                }
+            };
+            /**@type {GutterKeyboardHandler}*/
+            var gutterKeyboardHandler;
+
+            // If keyboard a11y mode is enabled we:
+            // - Enable keyboard operability gutter.
+            // - Prevent tab-trapping.
+            // - Hide irrelevant elements from assistive technology.
+            // - On Windows, set more lines to the textarea.
+            // - set aria-label to the text input.
+            if (value){
+                this.renderer.enableKeyboardAccessibility = true;
+                this.renderer.keyboardFocusClassName = "ace_keyboard-focus";
+
+                this.textInput.getElement().setAttribute("tabindex", -1);
+                // VoiceOver on Mac OS works best with single line in the textarea, the screen readers on
+                // Windows work best with multiple lines in the textarea.
+                this.textInput.setNumberOfExtraLines(useragent.isWin ? 3 : 0);
+                this.renderer.scroller.setAttribute("tabindex", 0);
+                this.renderer.scroller.setAttribute("role", "group");
+                this.renderer.scroller.setAttribute("aria-roledescription", nls("editor.scroller.aria-roledescription", "editor"));
+                this.renderer.scroller.classList.add(this.renderer.keyboardFocusClassName);
+                this.renderer.scroller.setAttribute("aria-label",
+                    nls("editor.scroller.aria-label", "Editor content, press Enter to start editing, press Escape to exit")
+                );
+
+                this.renderer.scroller.addEventListener("keyup", focusOnEnterKeyup.bind(this));
+                this.commands.addCommand(blurCommand);
+
+                this.renderer.$gutter.setAttribute("tabindex", 0);
+                this.renderer.$gutter.setAttribute("aria-hidden", false);
+                this.renderer.$gutter.setAttribute("role", "group");
+                this.renderer.$gutter.setAttribute("aria-roledescription", nls("editor.gutter.aria-roledescription", "editor gutter"));
+                this.renderer.$gutter.setAttribute("aria-label",
+                    nls("editor.gutter.aria-label", "Editor gutter, press Enter to interact with controls using arrow keys, press Escape to exit")
+                );
+                this.renderer.$gutter.classList.add(this.renderer.keyboardFocusClassName);
+
+                this.renderer.content.setAttribute("aria-hidden", true);
+
+                if (!gutterKeyboardHandler)
+                    gutterKeyboardHandler = new GutterKeyboardHandler(this);
+
+                gutterKeyboardHandler.addListener();
+
+                this.textInput.setAriaOptions({
+                    setLabel: true
+                });
+            } else {
+                this.renderer.enableKeyboardAccessibility = false;
+
+                this.textInput.getElement().setAttribute("tabindex", 0);
+                this.textInput.setNumberOfExtraLines(0);
+                this.renderer.scroller.setAttribute("tabindex", -1);
+                this.renderer.scroller.removeAttribute("role");
+                this.renderer.scroller.removeAttribute("aria-roledescription");
+                this.renderer.scroller.classList.remove(this.renderer.keyboardFocusClassName);
+                this.renderer.scroller.removeAttribute("aria-label");
+
+                this.renderer.scroller.removeEventListener("keyup", focusOnEnterKeyup.bind(this));
+                this.commands.removeCommand(blurCommand);
+
+                this.renderer.content.removeAttribute("aria-hidden");
+
+                this.renderer.$gutter.setAttribute("tabindex", -1);
+                this.renderer.$gutter.setAttribute("aria-hidden", true);
+                this.renderer.$gutter.removeAttribute("role");
+                this.renderer.$gutter.removeAttribute("aria-roledescription");
+                this.renderer.$gutter.removeAttribute("aria-label");
+                this.renderer.$gutter.classList.remove(this.renderer.keyboardFocusClassName);
+
+                if (gutterKeyboardHandler)
+                    gutterKeyboardHandler.removeListener();
+            }
+        },
+        initialValue: false
+    },
+    textInputAriaLabel: {
+        set: function(val) { this.$textInputAriaLabel = val; },
+        initialValue: ""
+    },
+    enableMobileMenu: {
+        /**
+         * @param {boolean} val
+         */
+        set: function(val) { this.$enableMobileMenu = val; },
+        initialValue: true
+    },
+    customScrollbar: "renderer",
+    hScrollBarAlwaysVisible: "renderer",
+    vScrollBarAlwaysVisible: "renderer",
+    highlightGutterLine: "renderer",
+    animatedScroll: "renderer",
+    showInvisibles: "renderer",
+    showPrintMargin: "renderer",
+    printMarginColumn: "renderer",
+    printMargin: "renderer",
+    fadeFoldWidgets: "renderer",
+    showFoldWidgets: "renderer",
+    displayIndentGuides: "renderer",
+    highlightIndentGuides: "renderer",
+    showGutter: "renderer",
+    fontSize: "renderer",
+    fontFamily: "renderer",
+    maxLines: "renderer",
+    minLines: "renderer",
+    scrollPastEnd: "renderer",
+    fixedWidthGutter: "renderer",
+    theme: "renderer",
+    hasCssTransforms: "renderer",
+    maxPixelHeight: "renderer",
+    useTextareaForIME: "renderer",
+    useResizeObserver: "renderer",
+    useSvgGutterIcons: "renderer",
+    showFoldedAnnotations: "renderer",
+
+    scrollSpeed: "$mouseHandler",
+    dragDelay: "$mouseHandler",
+    dragEnabled: "$mouseHandler",
+    focusTimeout: "$mouseHandler",
+    tooltipFollowsMouse: "$mouseHandler",
+
+    firstLineNumber: "session",
+    overwrite: "session",
+    newLineMode: "session",
+    useWorker: "session",
+    useSoftTabs: "session",
+    navigateWithinSoftTabs: "session",
+    tabSize: "session",
+    wrap: "session",
+    indentedSoftWrap: "session",
+    foldStyle: "session",
+    mode: "session"
+});
+
+
+var relativeNumberRenderer = {
+    getText: function(/**@type{EditSession}*/session, /**@type{number}*/row) {
+        return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? "\xb7" : ""))) + "";
+    },
+    getWidth: function(session, /**@type{number}*/lastLineNumber, config) {
+        return Math.max(
+            lastLineNumber.toString().length,
+            (config.lastRow + 1).toString().length,
+            2
+        ) * config.characterWidth;
+    },
+    update: function(e, /**@type{Editor}*/editor) {
+        editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER);
+    },
+    attach: function(/**@type{Editor}*/editor) {
+        editor.renderer.$gutterLayer.$renderer = this;
+        editor.on("changeSelection", this.update);
+        this.update(null, editor);
+    },
+    detach: function(/**@type{Editor}*/editor) {
+        if (editor.renderer.$gutterLayer.$renderer == this)
+            editor.renderer.$gutterLayer.$renderer = null;
+        editor.off("changeSelection", this.update);
+        this.update(null, editor);
+    }
+};
+exports.Editor = Editor;
diff --git a/demo/diff/index.html b/demo/diff/index.html
new file mode 100644
index 00000000000..d582a713c6e
--- /dev/null
+++ b/demo/diff/index.html
@@ -0,0 +1,273 @@
+
+
+
+    Ace-diff - Simple Demo #1
+
+    
+
+    
+
+
+ 
+
+
+ + + + + + diff --git a/demo/emmet.html b/demo/emmet.html index bd0d4abed7a..2b159bfe9cf 100644 --- a/demo/emmet.html +++ b/demo/emmet.html @@ -23,12 +23,12 @@

 
 
-
+
 
 
 
+
+
+
+
+
diff --git a/demo/inline_autocompletion.html b/demo/inline_autocompletion.html
new file mode 100644
index 00000000000..b514f670e5f
--- /dev/null
+++ b/demo/inline_autocompletion.html
@@ -0,0 +1,48 @@
+
+
+
+  
+  ACE Inline Autocompletion demo
+  
+
+
+
+

+
+
+
+
+
+
+
diff --git a/demo/keyboard_shortcuts.html b/demo/keyboard_shortcuts.html
index 3d01f559d44..ee74b5651d5 100644
--- a/demo/keyboard_shortcuts.html
+++ b/demo/keyboard_shortcuts.html
@@ -25,7 +25,7 @@
 
 
+
+        
+    
+
diff --git a/demo/kitchen-sink/docs/liquid.liquid b/demo/kitchen-sink/docs/liquid.liquid
index 29c0b016551..a06a7a7f4e2 100644
--- a/demo/kitchen-sink/docs/liquid.liquid
+++ b/demo/kitchen-sink/docs/liquid.liquid
@@ -1,4 +1,8 @@
-The following examples can be found in full at http://liquidmarkup.org/
+There are a couple of different Liquid variations in circulation. This grammars supports
+both the Standard and Shopify Liquid variations. The following examples can be found in full at:
+
+Standard Variation: https://shopify.github.io/liquid
+Shopify Variation: https://shopify.dev/docs/api/liquid
 
 Liquid is an extraction from the e-commerce system Shopify.
 Shopify powers many thousands of e-commerce stores which all call for unique designs.
@@ -37,11 +41,18 @@ Some more features include:
 
 

If

- {% if user.name == 'tobi' or user.name == 'marc' %} + {% if user.name == 'tobi' or user.name == 'marc' %} hi marc or tobi {% endif %}

+

Comments

+ +{% # Line Comment %} + +{% comment %} + Block Comment +{% endcomment %}

Case

@@ -58,7 +69,7 @@ Some more features include:

For Loops

- {% for item in array %} + {% for item in array %} {{ item }} {% endfor %}

@@ -74,3 +85,43 @@ Some more features include: {% endif %} {% endtablerow %}

+ +

Embedded Code Blocks

+ +This support Shopify Liquid variation JSON schema code blocks + +{% schema %} + { + "string": "bar", + "boolean": true, + "number": 100, + "object": { + "array": [100, false, "string", {}, [] ] + } + } +{% endschema %} + +This support Shopify Liquid variation Stylesheet and Style code blocks + +{% style %} + .class { + font-size: 10px; /* comment */ + } +{% endstyle %} + +{% stylesheet %} + .class { + font-size: 10px; /* comment */ + } +{% endstylesheet %} + +This support Shopify Liquid variation JavaScript code blocks + +{% javascript %} + + function foo (param) { + + return 'something' // comment + } + +{% endjavascript %} diff --git a/demo/kitchen-sink/docs/livescript.ls b/demo/kitchen-sink/docs/livescript.ls index ce082b4cb2d..d029ffae14d 100644 --- a/demo/kitchen-sink/docs/livescript.ls +++ b/demo/kitchen-sink/docs/livescript.ls @@ -1,4 +1,4 @@ -# Defines an editing mode for [Ace](http://ace.ajax.org). +# Defines an editing mode for [Ace](https://ace.c9.io). # # Open [test/ace.html](../test/ace.html) to test. diff --git a/demo/kitchen-sink/docs/logtalk.lgt b/demo/kitchen-sink/docs/logtalk.lgt new file mode 100644 index 00000000000..e01a1b8e926 --- /dev/null +++ b/demo/kitchen-sink/docs/logtalk.lgt @@ -0,0 +1,23 @@ +:- object(bottles). + + :- initialization(sing(99)). + + sing(0) :- + write('No more bottles of beer on the wall, no more bottles of beer.'), nl, + write('Go to the store and buy some more, 99 bottles of beer on the wall.'), nl, nl. + sing(N) :- + N > 0, + N2 is N - 1, + beers(N), write(' of beer on the wall, '), beers(N), write(' of beer.'), nl, + write('Take one down and pass it around, '), beers(N2), write(' of beer on the wall.'), nl, nl, + sing(N2). + + beers(0) :- + write('no more bottles'). + beers(1) :- + write('1 bottle'). + beers(N) :- + N > 1, + write(N), write(' bottles'). + +:- end_object. diff --git a/demo/kitchen-sink/docs/lua.lua b/demo/kitchen-sink/docs/lua.lua index 6c92719775b..66c652e1ceb 100644 --- a/demo/kitchen-sink/docs/lua.lua +++ b/demo/kitchen-sink/docs/lua.lua @@ -33,6 +33,6 @@ print([===[ --[=[-- table.maxn is deprecated, use # instead. --]=]-- -print(table.maxn{1,2,[4]=4,[8]=8) -- outputs 8 instead of 2 +print(table.maxn{1,2,[4]=4,[8]=8}) -- outputs 8 instead of 2 -print(5 --[[ blah ]]) \ No newline at end of file +print(5 --[[ blah ]]) diff --git a/demo/kitchen-sink/docs/mediawiki.wiki b/demo/kitchen-sink/docs/mediawiki.wiki new file mode 100644 index 00000000000..cb587b9280d --- /dev/null +++ b/demo/kitchen-sink/docs/mediawiki.wiki @@ -0,0 +1,31 @@ +{{Languages}} + +'''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. + +== Features == +* Syntax highlighting +* Automatic indent and outdent +* An optional command line +* Handles huge documents (100,000 lines and more are no problem) +* Fully customizable key bindings including VI and Emacs modes +* Themes (TextMate themes can be imported) +* Search and replace with regular expressions +* Highlight matching parentheses +* Toggle between soft tabs and real tabs +* Displays hidden characters +* Drag and drop text using the mouse +* Line wrapping +* Unstructured / user code folding +* Live syntax checker (currently JavaScript/CoffeeScript) + +== Take Ace for a spin! == +Check 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. + +If you want, you can use Ace as a textarea replacement thanks to the [http://ajaxorg.github.com/ace/build/textarea/editor.html Ace Bookmarklet]. + +== Documentation == +You find a lot more sample code in the [https://github.com/ajaxorg/ace/blob/master/demo/demo.js demo app]. + +There is also some documentation on the [https://github.com/ajaxorg/ace/wiki wiki page]. + +If you still need help, feel free to drop a mail on the [http://groups.google.com/group/ace-discuss ace mailing list]. diff --git a/demo/kitchen-sink/docs/mips.s b/demo/kitchen-sink/docs/mips.s new file mode 100644 index 00000000000..ec4f0091975 --- /dev/null +++ b/demo/kitchen-sink/docs/mips.s @@ -0,0 +1,18 @@ +# Original source from https://eng.libretexts.org +# Kann, Charles W., "Introduction To MIPS Assembly Language Programming" (2015). Open Textbooks. 2. +# https://cupola.gettysburg.edu/oer/2 + +# Program File: Program2-1.asm +# Author: Charles Kann +# Purpose: First program, Hello World +.text # Define the program instructions. +main: # Label to define the main program. + li $v0,4 # Load 4 into $v0 to indicate a print string. + la $a0, greeting # Load the address of the greeting into $a0. + syscall # Print greeting. The print is indicated by + # $v0 having a value of 4, and the string to + # print is stored at the address in $a0. + li $v0, 10 # Load a 10 (halt) into $v0. + syscall # The program ends. +.data # Define the program data. +greeting: .asciiz "Hello World" #The string to print. diff --git a/demo/kitchen-sink/docs/nasal.nas b/demo/kitchen-sink/docs/nasal.nas new file mode 100644 index 00000000000..daccc6b0bf1 --- /dev/null +++ b/demo/kitchen-sink/docs/nasal.nas @@ -0,0 +1,7 @@ +var sayHello = func(names, favorite) { + foreach (var name; names) { + printf("Hello %s, %s is the best!", name, favorite); + } +} + +sayHello(["World", "FlightGear"], "Nasal"); diff --git a/demo/kitchen-sink/docs/nginx.nginx b/demo/kitchen-sink/docs/nginx.nginx new file mode 100644 index 00000000000..5fec6bc14eb --- /dev/null +++ b/demo/kitchen-sink/docs/nginx.nginx @@ -0,0 +1,70 @@ +user www www; ## Default: nobody +worker_processes 5; ## Default: 1 +error_log logs/error.log; +pid logs/nginx.pid; +worker_rlimit_nofile 8192; + +events { + worker_connections 4096; ## Default: 1024 +} + +http { + include conf/mime.types; + include /etc/nginx/proxy.conf; + include /etc/nginx/fastcgi.conf; + index index.html index.htm index.php; + + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] $status ' + '"$request" $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log logs/access.log main; + sendfile on; + tcp_nopush on; + server_names_hash_bucket_size 128; # this seems to be required for some vhosts + + server { # php/fastcgi + listen 80; + server_name domain1.com www.domain1.com; + access_log logs/domain1.access.log main; + root html; + + location ~ \.php$ { + fastcgi_pass 127.0.0.1:1025; + } + } + + server { # simple reverse-proxy + listen 80; + server_name domain2.com www.domain2.com; + access_log logs/domain2.access.log main; + + # serve static files + location ~ ^/(images|javascript|js|css|flash|media|static)/ { + root /var/www/virtual/big.server.com/htdocs; + expires 30d; + } + + # pass requests for dynamic content to rails/turbogears/zope, et al + location / { + proxy_pass http://127.0.0.1:8080; + } + } + + upstream big_server_com { + server 127.0.0.3:8000 weight=5; + server 127.0.0.3:8001 weight=5; + server 192.168.0.1:8000; + server 192.168.0.1:8001; + } + + server { # simple load balancing + listen 80; + server_name big.server.com; + access_log logs/big.server.access.log main; + + location / { + proxy_pass http://big_server_com; + } + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/nim.nim b/demo/kitchen-sink/docs/nim.nim new file mode 100644 index 00000000000..834514ab2c5 --- /dev/null +++ b/demo/kitchen-sink/docs/nim.nim @@ -0,0 +1,15 @@ +#[ #[ Multiline comment in already + commented out code. ]# +proc p[T](x: T) = discard +]# +echo "This is code" +var + p = 0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64 + +proc getAlphabet(): string = + var accm = "" + for letter in 'a'..'z': # see iterators + accm.add(letter) + return accm + +assert("a" * 10 == "aaaaaaaaaa") diff --git a/demo/kitchen-sink/docs/Nix.nix b/demo/kitchen-sink/docs/nix.nix similarity index 100% rename from demo/kitchen-sink/docs/Nix.nix rename to demo/kitchen-sink/docs/nix.nix diff --git a/demo/kitchen-sink/docs/nunjucks.nunjucks b/demo/kitchen-sink/docs/nunjucks.nunjucks new file mode 100644 index 00000000000..8afecb52dd7 --- /dev/null +++ b/demo/kitchen-sink/docs/nunjucks.nunjucks @@ -0,0 +1,129 @@ +{{ foo.bar }} +{{ foo["bar"] }} +{{ foo | title }} +{{ foo | join(",") }} +{{ foo | replace("foo", "bar") | capitalize }} +{% block header %} +This is the default content +{% endblock %} + +
+ {% block left %}{% endblock %} +
+ +
+ {% block right %} + This is more content + {% endblock %} +
+{% extends "parent.html" %} + +{% block left %} +This is the left side! +{% endblock %} + +{% block right %} +This is the right side! +{% endblock %} + +{% block right %} +{{ super() }} +Right side! +{% endblock %} + +{% if variable %} + It is true +{% endif %} + +{% if hungry %} + I am hungry +{% elif tired %} + I am tired +{% else %} + I am good! +{% endif %} + +

Posts

+
    +{% for item in items %} +
  • {{ item.title }}
  • +{% else %} +
  • This would display if the 'item' collection were empty
  • +{% endfor %} +
+ +{% for ingredient, amount in food %} + Use {{ amount }} of {{ ingredient }} +{% endfor %} + +{% for fruit, color in fruits %} + Did you know that {{ fruit }} is {{ color }}? +{% endfor %} + +{% for x, y, z in points %} + Point: {{ x }}, {{ y }}, {{ z }} +{% endfor %} + +

Posts

+
    +{% asyncEach item in items %} + {% include "item-template.html" %} +{% endeach %} +
+ +

Posts

+
    +{% asyncAll item in items %} +
  • {{ item.id | lookup }}
  • +{% endall %} +
+ +{% macro field(name, value='', type='text') %} +
+ +
+{% endmacro %} + +{{ username }} +{% set username = "joe" %} +{{ username }} + +{% set standardModal %} + {% include 'standardModalData.html' %} +{% endset %} + +
+ +{% set standardModal %} + {% include 'standardModalData.html' %} +{% endset %} + +
+ +{% include "missing.html" ignore missing %} + +{% import "forms.html" as forms %} + +{{ forms.label('Username') }} +{{ forms.field('user') }} +{{ forms.label('Password') }} +{{ forms.field('pass', type='password') }} + +{% from "forms.html" import field, label as description %} + +{{ description('Username') }} +{{ field('user') }} +{{ description('Password') }} +{{ field('pass', type='password') }} + +{{ foo(1, 2, bar=3, baz=4) }} + +{# Loop through all the users #} +{% for user in users %}...{% endfor %} + + +{% set cls = cycler("odd", "even") %} +{% for row in rows %} +
{{ row.name }}
+{% endfor %} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/odin.odin b/demo/kitchen-sink/docs/odin.odin new file mode 100644 index 00000000000..61a3d911ee0 --- /dev/null +++ b/demo/kitchen-sink/docs/odin.odin @@ -0,0 +1,21 @@ +package main + +import "core:fmt" + +main :: proc() { + program := "+ + * 😃 - /" + accumulator := 0 + + for token in program { + switch token { + case '+': accumulator += 1 + case '-': accumulator -= 1 + case '*': accumulator *= 2 + case '/': accumulator /= 2 + case '😃': accumulator *= accumulator + case: // Ignore everything else + } + } + + fmt.printf("The program \"%s\" calculates the value %d\n", program, accumulator) +} diff --git a/demo/kitchen-sink/docs/partiql.partiql b/demo/kitchen-sink/docs/partiql.partiql new file mode 100644 index 00000000000..a38956799c7 --- /dev/null +++ b/demo/kitchen-sink/docs/partiql.partiql @@ -0,0 +1,59 @@ +-- comment +/* multi + line + comment */ + +SELECT "a", b, c FROM stuff s INNER CROSS JOIN @s WHERE f(s) -- comment +-- comment + +SELECT VALUE {'sensor': s.sensor, + 'readings': (SELECT VALUE l.co + FROM logs as l + WHERE l.sensor = s.sensor + ) + } +FROM sensors AS s + +SELECT VALUE (PIVOT v AT g + FROM UNPIVOT r as v At g + WHERE g LIKE 'co%') +FROM sensors AS r + + +SELECT x.* +FROM [{'a':1, 'b':1}, {'a':2}, 'foo'] AS x + +-- NOTE: the embedded ion values parse as ion (inside the backticks "`") +SELECT x.* +FROM `[{'a':1, 'b':1}, {'a':2}, "foo"]` AS x + +SELECT VALUE {v.a: v.b, v.c: v.d} +FROM <<{'a':'same', 'b':1, 'c':'same', 'd':2}>> AS v +WHERE v.b + +SELECT u.id, feedbackId, commentId, upvoteId +FROM users as u, u.feedbacks as feedback at feedbackId +LEFT CROSS JOIN feedback.comments as comment AT commentId +LEFT CROSS JOIN UNPIVOT comment.upvotes as upvote at upvoteId + + +SELECT ( + SELECT numRec, tabulated + FROM committed.changes changes, + (SELECT u.id, feedbackId, commentId, upvoteId + FROM changes.tabulated as u, + u.feedbacks as feedback at feedbackId LEFT CROSS JOIN feedback.comments as comment AT commentId + LEFT CROSS JOIN UNPIVOT comment.upvotes as upvote at upvoteId + ) as tabulated, + changes.numRec as numRec + ) + AS changes + FROM incoming_committed committed + +SELECT SUM(AVG(n)) FROM <> AS n + + +SELECT attributeId, COUNT(*) as the_count +FROM repeating_things +GROUP BY attributeId GROUP AS g +HAVING 1 = 0 \ No newline at end of file diff --git a/demo/kitchen-sink/docs/pgsql.pgsql b/demo/kitchen-sink/docs/pgsql.pgsql index ef265cdcbe7..8dc727b1bf3 100644 --- a/demo/kitchen-sink/docs/pgsql.pgsql +++ b/demo/kitchen-sink/docs/pgsql.pgsql @@ -116,3 +116,14 @@ lines - use dollar quotes $$; END; + +-- Anonymous code block +DO LANGUAGE plpgsql $$ +BEGIN + -- code block +END $$; + +DO $$ +BEGIN + -- code block +END; $$; diff --git a/demo/kitchen-sink/docs/php_laravel_blade.blade.php b/demo/kitchen-sink/docs/php_laravel_blade.blade.php index dfa62115909..39ca09c3d5b 100644 --- a/demo/kitchen-sink/docs/php_laravel_blade.blade.php +++ b/demo/kitchen-sink/docs/php_laravel_blade.blade.php @@ -65,4 +65,18 @@ @yield('content')
- \ No newline at end of file + + + +{{-- comment --}} + +@if ( + {{-- comment --}} + /*block comment*/ + #another comment + $user->type == 1 + // c comment + /* comment*/ +) + # not a comment
+@endif diff --git a/demo/kitchen-sink/docs/plsql.plsql b/demo/kitchen-sink/docs/plsql.plsql new file mode 100644 index 00000000000..b51ac5471dc --- /dev/null +++ b/demo/kitchen-sink/docs/plsql.plsql @@ -0,0 +1,18 @@ +create table t ( + id integer, + month varchar(3), + value integer +); + +insert into t (month, value) values ('jan', 1); +insert into t (month, value) values ('jan', 1); +insert into t (month, value) values ('oct', 3); +insert into t (month, value) values ('dec', 96); + + +select * from (select month, value from t) +pivot +( + sum(value) + for month in ('jan', 'oct', 'dec') +); \ No newline at end of file diff --git a/demo/kitchen-sink/docs/powershell.ps1 b/demo/kitchen-sink/docs/powershell.ps1 index f3a70bc1a0b..1b4c46c06c7 100644 --- a/demo/kitchen-sink/docs/powershell.ps1 +++ b/demo/kitchen-sink/docs/powershell.ps1 @@ -22,3 +22,45 @@ $an_array = @(1, 2, 3) $a_hash = @{"something" = "something else"} & notepad .\readme.md + +$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 } +$last = "Anderson"; $IDNum = 120 +$h2 = @{ FirstName = "James"; LastName = $last; IDNum = $IDNum + 3 } +$h3 = @{ } +$h4 = @{ 10 = "James"; 20.5 = "Anderson"; $true = 123 } + +${Maximum_Count_26} +${Name with`twhite space and `{punctuation`}} +${E:\\File.txt} + +"C:\Temp\" {mkdir "C:\Temp\"} +"C:\Temp\" + +@" +This is a here string +$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 } +$last = "Anderson"; $IDNum = 120 +$h2 = @{ FirstName = "James"; LastName = $last; IDNum = $IDNum + 3 } +$h3 = @{ } +$h4 = @{ 10 = "James"; 20.5 = "Anderson"; $true = 123 } +$j = 20 + +still string +$($i = 10) # pipeline gets nothing +$(($i = 10)) # pipeline gets int 10 +$($i = 10; $j) # pipeline gets int 20 +$(($i = 10); $j) # pipeline gets [object[]](10,20) +$(($i = 10); ++$j) # pipeline gets int 10 +$(($i = 10); (++$j)) # pipeline gets [object[]](10,22) +$($i = 10; ++$j) # pipeline gets nothing +$(2,4,6) # pipeline gets [object[]](2,4,6) +"@ + +@' +Expressions inside should be recognised as string +$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 } +$last = "Anderson"; $IDNum = 120 +$h2 = @{ FirstName = "James"; LastName = $last; IDNum = $IDNum + 3 } +$h3 = @{ } +$h4 = @{ 10 = "James"; 20.5 = "Anderson"; $true = 123 } +'@ diff --git a/demo/kitchen-sink/docs/prisma.prisma b/demo/kitchen-sink/docs/prisma.prisma new file mode 100644 index 00000000000..56699d12758 --- /dev/null +++ b/demo/kitchen-sink/docs/prisma.prisma @@ -0,0 +1,334 @@ +generator photon { + provider = "photonjs" +} + +model User { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + firstName String + lastName String + email String @unique + password String + phone String + responseRate Float? + responseTime Int? + ReportsTo User? @relation("EmployeeToEmployee_ReportsTo") + employees User[] @relation("EmployeeToEmployee_ReportsTo") + isSuperHost Boolean + ownedPlaces Place[] + location Location? + bookings Booking[] + paymentAccount PaymentAccount[] + sentMessages Message[] @relation("SentMessages") + receivedMessages Message[] @relation("ReceivedMessages") + notifications Notification[] + profilePicture Picture? + hostingExperiences Experience[] +} + +model Place { + id String @default(cuid()) @id + name String + size PLACE_SIZES? + shortDescription String + description String + slug String + maxGuests Int + numBedrooms Int + numBeds Int + numBaths Int + reviews Review[] + amenities Amenities + host User + pricing Pricing + location Location + views Views + guestRequirements GuestRequirements? + policies Policies? + houseRules HouseRules? + bookings Booking[] + pictures Picture[] + popularity Int +} + +model Pricing { + id String @default(cuid()) @id + place Place + monthlyDiscount Int? + weeklyDiscount Int? + perNight Int + smartPricing Boolean + basePrice Int + averageWeekly Int + averageMonthly Int + cleaningFee Int? + securityDeposit Int? + extraGuests Int? + weekendPricing Int? + currency CURRENCY? +} + +model GuestRequirements { + id String @default(cuid()) @id + govIssuedId Boolean + recommendationsFromOtherHosts Boolean + guestTripInformation Boolean + place Place +} + +model Policies { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + checkInStartTime Float + checkInEndTime Float + checkoutTime Float + place Place +} + +model HouseRules { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + suitableForChildren Boolean? + suitableForInfants Boolean? + petsAllowed Boolean? + smokingAllowed Boolean? + partiesAndEventsAllowed Boolean? + additionalRules String? +} + +model Views { + id String @default(cuid()) @id + lastWeek Int + place Place +} + +model Location { + id String @default(cuid()) @id + lat Float + lng Float + neighbourHood Neighbourhood? + user User? + place Place? + address String + directions String + experience Experience? + restaurant Restaurant? +} + +model Neighbourhood { + id String @default(cuid()) @id + locations Location[] + name String + slug String + homePreview Picture? + city City + featured Boolean + popularity Int +} + +model City { + id String @default(cuid()) @id + name String + neighbourhoods Neighbourhood[] +} + +model Picture { + id String @default(cuid()) @id + url String +} + +model Experience { + id String @default(cuid()) @id + category ExperienceCategory? + title String + host User + location Location + pricePerPerson Int + reviews Review[] + preview Picture + popularity Int +} + +model ExperienceCategory { + id String @default(cuid()) @id + mainColor String + name String + experience Experience? +} + +model Amenities { + id String @default(cuid()) @id + place Place + elevator Boolean + petsAllowed Boolean + internet Boolean + kitchen Boolean + wirelessInternet Boolean + familyKidFriendly Boolean + freeParkingOnPremises Boolean + hotTub Boolean + pool Boolean + smokingAllowed Boolean + wheelchairAccessible Boolean + breakfast Boolean + cableTv Boolean + suitableForEvents Boolean + dryer Boolean + washer Boolean + indoorFireplace Boolean + tv Boolean + heating Boolean + hangers Boolean + iron Boolean + hairDryer Boolean + doorman Boolean + paidParkingOffPremises Boolean + freeParkingOnStreet Boolean + gym Boolean + airConditioning Boolean + shampoo Boolean + essentials Boolean + laptopFriendlyWorkspace Boolean + privateEntrance Boolean + buzzerWirelessIntercom Boolean + babyBath Boolean + babyMonitor Boolean + babysitterRecommendations Boolean + bathtub Boolean + changingTable Boolean + childrensBooksAndToys Boolean + childrensDinnerware Boolean + crib Boolean +} + +model Review { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + text String + stars Int + accuracy Int + location Int + checkIn Int + value Int + cleanliness Int + communication Int + place Place + experience Experience? +} + +model Booking { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + bookee User + place Place + startDate DateTime + endDate DateTime + payment Payment? +} + +model Payment { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + serviceFee Float + placePrice Float + totalPrice Float + booking Booking + paymentMethod PaymentAccount +} + +model PaymentAccount { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + type PAYMENT_PROVIDER? + user User + payments Payment[] + paypal PaypalInformation? + creditcard CreditCardInformation? +} + +model PaypalInformation { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + email String + paymentAccount PaymentAccount +} + +model CreditCardInformation { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + cardNumber String + expiresOnMonth Int + expiresOnYear Int + securityCode String + firstName String + lastName String + postalCode String + country String + paymentAccount PaymentAccount? +} + +model Message { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + from User @relation("SentMessages") + to User @relation("ReceivedMessages") + deliveredAt DateTime + readAt DateTime +} + +model Notification { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + type NOTIFICATION_TYPE? + user User + link String + readDate DateTime +} + +model Restaurant { + id String @default(cuid()) @id + createdAt DateTime @default(now()) + title String + avgPricePerPerson Int + pictures Picture[] + location Location + isCurated Boolean + slug String + popularity Int +} + +enum CURRENCY { + CAD + CHF + EUR + JPY + USD + ZAR +} + +enum PLACE_SIZES { + ENTIRE_HOUSE + ENTIRE_APARTMENT + ENTIRE_EARTH_HOUSE + ENTIRE_CABIN + ENTIRE_VILLA + ENTIRE_PLACE + ENTIRE_BOAT + PRIVATE_ROOM +} + +enum PAYMENT_PROVIDER { + PAYPAL + CREDIT_CARD +} + +enum NOTIFICATION_TYPE { + OFFER + INSTANT_BOOK + RESPONSIVENESS + NEW_AMENITIES + HOUSE_RULES +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/prql.prql b/demo/kitchen-sink/docs/prql.prql new file mode 100644 index 00000000000..5387d697b6f --- /dev/null +++ b/demo/kitchen-sink/docs/prql.prql @@ -0,0 +1,22 @@ +from invoices +filter invoice_date >= @1970-01-16 +derive { + transaction_fees = 0.8, + income = total - transaction_fees +} +filter income > 1 +group customer_id ( + aggregate { + average total, + sum_income = sum income, + ct = count total, + } +) +sort {-sum_income} +take 10 +join c=customers (==customer_id) +derive name = f"{c.last_name}, {c.first_name}" +select { + c.customer_id, name, sum_income +} +derive db_version = s"version()" diff --git a/demo/kitchen-sink/docs/puppet.epp b/demo/kitchen-sink/docs/puppet.epp new file mode 100644 index 00000000000..bc070681a2a --- /dev/null +++ b/demo/kitchen-sink/docs/puppet.epp @@ -0,0 +1,51 @@ +define apache::vhost ($port, $docroot, $servername = $title, $vhost_name = '*') { + include apache + include apache::params + $vhost_dir = $apache::params::vhost_dir + file { "${vhost_dir}/${servername}.conf": + content => template('apache/vhost-default.conf.erb'), + owner => 'www', + group => 'www', + mode => '644', + require => Package['httpd'], + notify => Service['httpd'], + } +} + +type MyModule::Tree = Array[Variant[Data, Tree]] + +function apache::bool2http(Variant[String, Boolean] $arg) >> String { + case $arg { + false, undef, /(?i:false)/ : { 'Off' } + true, /(?i:true)/ : { 'On' } + default : { "$arg" } + } +} + +# A class with parameters +class apache (String $version = 'latest') { + package {'httpd': + ensure => $version, # Using the class parameter from above + before => File['/etc/httpd.conf'], + } + file {'/etc/httpd.conf': + ensure => file, + owner => 'httpd', + content => template('apache/httpd.conf.erb'), # Template from a module + } + service {'httpd': + ensure => running, + enable => true, + subscribe => File['/etc/httpd.conf'], + } +} + + +if $is_virtual { + warning( 'Tried to include class ntp on virtual machine; this node might be misclassified.' ) +} +elsif $operatingsystem == 'Darwin' { + warning( 'This NTP module does not yet work on our Mac laptops.' ) +else { + include ntp +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/qml.qml b/demo/kitchen-sink/docs/qml.qml new file mode 100644 index 00000000000..17c3e0398a2 --- /dev/null +++ b/demo/kitchen-sink/docs/qml.qml @@ -0,0 +1,22 @@ +// A simple example +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +Rectangle { + color: "red" + anchors.fill: parent + + Text { + text: "WEEEEEEEEEE" + font.pixelSize: 50 + color: "white" + anchors.centerIn: parent + RotationAnimator on rotation { + running: true + loops: Animation.Infinite + from: 0 + to: 360 + duration: 1500 + } + } +} diff --git a/demo/kitchen-sink/docs/raku.raku b/demo/kitchen-sink/docs/raku.raku new file mode 100644 index 00000000000..b696e8c11e3 --- /dev/null +++ b/demo/kitchen-sink/docs/raku.raku @@ -0,0 +1,41 @@ +=begin comment +Raku example for ace +=end comment +class Cook is Employee { + has @.utensils is rw; + has @.cookbooks is rw; + + method cook( $food ) { + say "Cooking $food"; + } + + method clean_utensils { + say "Cleaning $_" for @.utensils; + } +} + +class Baker is Cook { + method cook( $confection ) { + say "Baking a tasty $confection"; + } +} + +my $cook = Cook.new( + utensils => , + cookbooks => 'The Joy of Cooking', + salary => 40000); + +$cook.cook( 'pizza' ); # OUTPUT: «Cooking pizza␤» +say $cook.utensils.perl; # OUTPUT: «["spoon", "ladle", "knife", "pan"]␤» +say $cook.cookbooks.perl; # OUTPUT: «["The Joy of Cooking"]␤» +say $cook.salary; # OUTPUT: «40000␤» + +my $baker = Baker.new( + utensils => 'self cleaning oven', + cookbooks => "The Baker's Apprentice", + salary => 50000); + +$baker.cook('brioche'); # OUTPUT: «Baking a tasty brioche␤» +say $baker.utensils.perl; # OUTPUT: «["self cleaning oven"]␤» +say $baker.cookbooks.perl; # OUTPUT: «["The Baker's Apprentice"]␤» +say $baker.salary; # OUTPUT: «50000␤» diff --git a/demo/kitchen-sink/docs/red.red b/demo/kitchen-sink/docs/red.red index d4d76d96f8c..b6c9c1d42cf 100644 --- a/demo/kitchen-sink/docs/red.red +++ b/demo/kitchen-sink/docs/red.red @@ -1,62 +1,62 @@ -Red [] -info: func ['fn /name /intro /args /refinements /locals /return /spec - /arg-num /arg-names /arg-types /ref-names /ref-types /ref-num /type - /local intr ars refs locs ret arg ref typ -][ - intr: copy "" ars: make map! copy [] refs: make map! copy [] locs: copy [] ret: copy [] typ: ref-arg: ref-arg-type: none - if lit-word? fn [fn: to-word fn] - unless find [op! native! function! action!] type?/word get fn [ - cause-error 'user 'message ["Only function types accepted!"] - ] - out: make map! copy [] - specs: spec-of get fn - parse specs [ - opt [set intr string!] - any [set arg [word! | lit-word!] opt [set typ block!] opt string! (put ars arg either typ [typ][[any-type!]])] - any [set ref refinement! [ - if (ref <> /local) (put refs to-lit-word ref make map! copy []) - opt string! - any [set ref-arg word! opt [set ref-arg-type block!] - (put refs/(to-word ref) to-lit-word ref-arg either ref-arg-type [ref-arg-type][[any-type!]]) - ] - | any [set loc word! (append locs loc) opt string!] - opt [set-word! set ret block!] - ]] - - ( - out: case [ - name [to-word fn] - intro [intr] - args [ars] - arg-num [length? ars] - arg-names [copy keys-of ars] - arg-types [copy values-of ars] - refinements [refs] - ref-names [copy keys-of refs] - ref-types [copy values-of refs] - ref-num [length? refs] - locals [locs] - return [ret] - spec [specs] - true [ - make object! [ - name: to-word fn - intro: intr - args: ars - refinements: refs - locals: locs - return: ret - spec: specs - type: type? get fn - arg-num: length? args - arg-names: copy keys-of args - arg-types: copy values-of args - ref-names: copy keys-of refinements - ref-types: copy values-of refinements - ref-num: length? refinements - ] - ] - ]) - ] - out -] +Red [] +info: func ['fn /name /intro /args /refinements /locals /return /spec + /arg-num /arg-names /arg-types /ref-names /ref-types /ref-num /type + /local intr ars refs locs ret arg ref typ +][ + intr: copy "" ars: make map! copy [] refs: make map! copy [] locs: copy [] ret: copy [] typ: ref-arg: ref-arg-type: none + if lit-word? fn [fn: to-word fn] + unless find [op! native! function! action!] type?/word get fn [ + cause-error 'user 'message ["Only function types accepted!"] + ] + out: make map! copy [] + specs: spec-of get fn + parse specs [ + opt [set intr string!] + any [set arg [word! | lit-word!] opt [set typ block!] opt string! (put ars arg either typ [typ][[any-type!]])] + any [set ref refinement! [ + if (ref <> /local) (put refs to-lit-word ref make map! copy []) + opt string! + any [set ref-arg word! opt [set ref-arg-type block!] + (put refs/(to-word ref) to-lit-word ref-arg either ref-arg-type [ref-arg-type][[any-type!]]) + ] + | any [set loc word! (append locs loc) opt string!] + opt [set-word! set ret block!] + ]] + + ( + out: case [ + name [to-word fn] + intro [intr] + args [ars] + arg-num [length? ars] + arg-names [copy keys-of ars] + arg-types [copy values-of ars] + refinements [refs] + ref-names [copy keys-of refs] + ref-types [copy values-of refs] + ref-num [length? refs] + locals [locs] + return [ret] + spec [specs] + true [ + make object! [ + name: to-word fn + intro: intr + args: ars + refinements: refs + locals: locs + return: ret + spec: specs + type: type? get fn + arg-num: length? args + arg-names: copy keys-of args + arg-types: copy values-of args + ref-names: copy keys-of refinements + ref-types: copy values-of refinements + ref-num: length? refinements + ] + ] + ]) + ] + out +] diff --git a/demo/kitchen-sink/docs/robot.robot b/demo/kitchen-sink/docs/robot.robot new file mode 100644 index 00000000000..0fac30e212d --- /dev/null +++ b/demo/kitchen-sink/docs/robot.robot @@ -0,0 +1,209 @@ +*** Settings *** +Documentation Robot Framework 4 syntax recipes cheat sheet robot. +... Demonstrates Robot Framework syntax in a concise format. +Library MyLibrary +Library MyLibrary WITH NAME HelloLibrary +Library MyLibrary greeting=Howdy! WITH NAME HowdyLibrary +Resource keywords.robot +Suite Setup Log Suite Setup! +Suite Teardown Log Suite Teardown! +Test Setup Log Test Setup! +Test Teardown Log Test Teardown! +Test Timeout 2 minutes +Variables variables.py + +*** Variables *** +${STRING}= cat +${NUMBER}= ${1} +@{LIST}= one two three +&{DICTIONARY}= string=${STRING} number=${NUMBER} list=@{LIST} +${ENVIRONMENT_VARIABLE}= %{PATH=Default value} + +*** Keywords *** +A keyword without arguments + Log No arguments. + +A keyword with a required argument + [Arguments] ${argument} + Log Required argument: ${argument} + +A keyword with an optional argument + [Arguments] ${argument}=Default value + Log Optional argument: ${argument} + ... Another arg + +A keyword with any number of arguments + [Arguments] @{varargs} + Log Any number of arguments: @{varargs} + +A keyword with one or more arguments + [Arguments] ${argument} @{varargs} + Log One or more arguments: ${argument} @{varargs} + +A keyword that returns a value + [Return] Return value + +A keyword with documentation + [Documentation] This is keyword documentation. + No Operation + +*** Test Cases *** +Call keywords with a varying number of arguments + [Tags] Test Another Tag + A keyword without arguments + A keyword with a required argument Argument + A keyword with a required argument argument=Argument + A keyword with an optional argument + A keyword with an optional argument Argument + A keyword with an optional argument argument=Argument + A keyword with any number of arguments + A keyword with any number of arguments arg1 arg2 arg3 arg4 arg5 + A keyword with one or more arguments arg1 + A keyword with one or more arguments arg1 arg2 arg3 + +Call a keyword that returns a value + ${value}= A keyword that returns a value + Log ${value} # Return value + +Do conditional IF - ELSE IF - ELSE execution + IF ${NUMBER} > 1 + Log Greater than one. + ELSE IF "${STRING}" == "dog" + Log It's a dog! + ELSE + Log Probably a cat. 🤔 + END + +Loop a list + Log ${LIST} # ['one', 'two', 'three'] + FOR ${item} IN @{LIST} + Log ${item} # one, two, three + END + FOR ${item} IN one two three + Log ${item} # one, two, three + END + +Loop a dictionary + Log ${DICTIONARY} + # {'string': 'cat', 'number': 1, 'list': ['one', 'two', 'three']} + FOR ${key_value_tuple} IN &{DICTIONARY} + Log ${key_value_tuple} + # ('string', 'cat'), ('number', 1), ('list', ['one', 'two', 'three']) + END + FOR ${key} IN @{DICTIONARY} + Log ${key}=${DICTIONARY}[${key}] + # string=cat, number=1, list=['one', 'two', 'three'] + END + +Loop a range from 0 to end index + FOR ${index} IN RANGE 10 + Log ${index} # 0-9 + END + +Loop a range from start to end index + FOR ${index} IN RANGE 1 10 + Log ${index} # 1-9 + END + +Loop a range from start to end index with steps + FOR ${index} IN RANGE 0 10 2 + Log ${index} # 0, 2, 4, 6, 8 + END + +Nest loops + @{alphabets}= Create List a b c + Log ${alphabets} # ['a', 'b', 'c'] + @{numbers}= Create List ${1} ${2} ${3} + Log ${numbers} # [1, 2, 3] + FOR ${alphabet} IN @{alphabets} + FOR ${number} IN @{numbers} + Log ${alphabet}${number} + # a1, a2, a3, b1, b2, b3, c1, c2, c3 + END + END + +Exit a loop on condition + FOR ${i} IN RANGE 5 + Exit For Loop If ${i} == 2 + Log ${i} # 0, 1 + END + +Continue a loop from the next iteration on condition + FOR ${i} IN RANGE 3 + Continue For Loop If ${i} == 1 + Log ${i} # 0, 2 + END + +Create a scalar variable + ${animal}= Set Variable dog + Log ${animal} # dog + Log ${animal}[0] # d + Log ${animal}[-1] # g + +Create a number variable + ${π}= Set Variable ${3.14} + Log ${π} # 3.14 + +Create a list variable + @{animals}= Create List dog cat bear + Log ${animals} # ['dog', 'cat', 'bear'] + Log ${animals}[0] # dog + Log ${animals}[-1] # bear + +Create a dictionary variable + &{dictionary}= Create Dictionary key1=value1 key2=value2 + Log ${dictionary} # {'key1': 'value1', 'key2': 'value2'} + Log ${dictionary}[key1] # value1 + Log ${dictionary.key2} # value2 + +Access the items in a sequence (list, string) + ${string}= Set Variable Hello world! + Log ${string}[0] # H + Log ${string}[:5] # Hello + Log ${string}[6:] # world! + Log ${string}[-1] # ! + @{list}= Create List one two three four five + Log ${list} # ['one', 'two', 'three', 'four', 'five'] + Log ${list}[0:6:2] # ['one', 'three', 'five'] + +Call a custom Python library + ${greeting}= MyLibrary.Get Greeting + Log ${greeting} # Hello! + ${greeting}= HelloLibrary.Get Greeting + Log ${greeting} # Hello! + ${greeting}= HowdyLibrary.Get Greeting + Log ${greeting} # Howdy! + +Call a keyword from a separate resource file + My keyword in a separate resource file + +Access a variable in a separate variable file + Log ${MY_VARIABLE_FROM_A_SEPARATE_VARIABLE_FILE} + +Split arguments to multiple lines + A keyword with any number of arguments + ... arg1 + ... arg2 + ... arg3 + +Log available variables + Log Variables + # ${/} = / + # &{DICTIONARY} = { string=cat | number=1 | list=['one', 'two', 'three'] } + # ${OUTPUT_DIR} = /Users//... + # ... + +Evaluate Python expressions + ${path}= Evaluate os.environ.get("PATH") + ${path}= Set Variable ${{os.environ.get("PATH")}} + +Use special variables + Log ${EMPTY} # Like the ${SPACE}, but without the space. + Log ${False} # Boolean False. + Log ${None} # Python None + Log ${null} # Java null. + Log ${SPACE} # ASCII space (\x20). + Log ${SPACE * 4} # Four spaces. + Log "${SPACE}" # Quoted space (" "). + Log ${True} # Boolean True. + LOG ${CURDIR} # Current directory diff --git a/demo/kitchen-sink/docs/rust.rs b/demo/kitchen-sink/docs/rust.rs index 7ab5418cdfb..4611f376ea5 100644 --- a/demo/kitchen-sink/docs/rust.rs +++ b/demo/kitchen-sink/docs/rust.rs @@ -18,3 +18,47 @@ fn map(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] { } return accumulator; } + +struct ConstGenericStruct([(); N]); +// T constrains by being an argument to GenericTrait. +impl GenericTrait for i32 { /* ... */ } + +// T constrains by being an arguement to GenericStruct +impl Trait for GenericStruct { /* ... */ } + +// Likewise, N constrains by being an argument to ConstGenericStruct +impl Trait for ConstGenericStruct { /* ... */ } + +// T constrains by being in an associated type in a bound for type `U` which is +// itself a generic parameter constraining the trait. +impl GenericTrait for u32 where U: HasAssocType { /* ... */ } + +// Like previous, except the type is `(U, isize)`. `U` appears inside the type +// that includes `T`, and is not the type itself. +impl GenericStruct where (U, isize): HasAssocType { /* ... */ } + +//! - Inner line doc +//!! - Still an inner line doc (but with a bang at the beginning) + +/*! - Inner block doc */ +/*!! - Still an inner block doc (but with a bang at the beginning) */ + +/** - Outer block doc (exactly) 2 asterisks */ +let multiline = r##" + This is a raw string. + r#"nested string"# +"##; +let empty = br##""##; +let _strings = [r"hello\", br"hello\", cr"hello\" ]; + +macro_rules! mac_variant { + ($vis:vis $name:ident) => { + enum $name { + $vis Unit, + + $vis Tuple(u8, u16), + + $vis Struct { f: u8 }, + } + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/sac.sac b/demo/kitchen-sink/docs/sac.sac new file mode 100644 index 00000000000..75887980727 --- /dev/null +++ b/demo/kitchen-sink/docs/sac.sac @@ -0,0 +1,75 @@ +/***************************************************************************** + * + * SAC demo program + * + * This SAC demo program implements 2-dimensional relaxation on double + * precision floating point numbers applying a 4-point stencil and fixed + * boundary conditions. + * + * The vertical (SIZE1) and the horizontal (SIZE2) array size as well as + * the number of iterations to be performed (LOOP) may be set at compile + * time. + * + *****************************************************************************/ + +#ifndef LOOP +#define LOOP 100 +#endif + +#ifndef SIZE1 +#define SIZE1 1000 +#endif + +#ifndef SIZE2 +#define SIZE2 1000 +#endif + +use Array: all; +use StdIO: all; + +inline +double[+] onestep(double[+] B) +{ + A = with { + ( . < x < . ) : 0.25*(B[x+[1,0]] + + B[x-[1,0]] + + B[x+[0,1]] + + B[x-[0,1]]); + } : modarray( B ); + + return(A); +} + +inline +double[+] relax(double[+] A, int steps) +{ + for (k=0; k 0) { + bytes top = stk[0 : 1]; + m = unpack(top); + + // pop + stk = stk[1 : len(stk)]; + + if (m == 0) { + n = n + m + 1; + } + else if (n == 0) { + n++; + m--; + // push + stk = num2bin(m, 1) + stk; + } + else { + stk = num2bin(m - 1, 1) + stk; + stk = num2bin(m, 1) + stk; + n--; + } + } + } + + return n; + } + + // y = 5 + public function unlock(int y) { + require(y == this.ackermann(this.a, this.b)); + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/smithy.smithy b/demo/kitchen-sink/docs/smithy.smithy new file mode 100644 index 00000000000..ed5a9132468 --- /dev/null +++ b/demo/kitchen-sink/docs/smithy.smithy @@ -0,0 +1,130 @@ +namespace example.weather + +/// Provides weather forecasts. +@paginated(inputToken: "nextToken", outputToken: "nextToken", + pageSize: "pageSize") +service Weather { + version: "2006-03-01", + resources: [City], + operations: [GetCurrentTime] +} + +resource City { + identifiers: { cityId: CityId }, + read: GetCity, + list: ListCities, + resources: [Forecast], +} + +resource Forecast { + identifiers: { cityId: CityId }, + read: GetForecast, +} + +// "pattern" is a trait. +@pattern("^[A-Za-z0-9 ]+$") +string CityId + +@readonly +operation GetCity { + input: GetCityInput, + output: GetCityOutput, + errors: [NoSuchResource] +} + +structure GetCityInput { + // "cityId" provides the identifier for the resource and + // has to be marked as required. + @required + cityId: CityId +} + +structure GetCityOutput { + // "required" is used on output to indicate if the service + // will always provide a value for the member. + @required + name: String, + + @required + coordinates: CityCoordinates, +} + +// This structure is nested within GetCityOutput. +structure CityCoordinates { + @required + latitude: Float, + + @required + longitude: Float, +} + +// "error" is a trait that is used to specialize +// a structure as an error. +@error("client") +structure NoSuchResource { + @required + resourceType: String +} + +// The paginated trait indicates that the operation may +// return truncated results. +@readonly +@paginated(items: "items") +operation ListCities { + input: ListCitiesInput, + output: ListCitiesOutput +} + +structure ListCitiesInput { + nextToken: String, + pageSize: Integer +} + +structure ListCitiesOutput { + nextToken: String, + + @required + items: CitySummaries, +} + +// CitySummaries is a list of CitySummary structures. +list CitySummaries { + member: CitySummary +} + +// CitySummary contains a reference to a City. +@references([{resource: City}]) +structure CitySummary { + @required + cityId: CityId, + + @required + name: String, +} + +@readonly +operation GetCurrentTime { + output: GetCurrentTimeOutput +} + +structure GetCurrentTimeOutput { + @required + time: Timestamp +} + +@readonly +operation GetForecast { + input: GetForecastInput, + output: GetForecastOutput +} + +// "cityId" provides the only identifier for the resource since +// a Forecast doesn't have its own. +structure GetForecastInput { + @required + cityId: CityId, +} + +structure GetForecastOutput { + chanceOfRain: Float +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/terraform.tf b/demo/kitchen-sink/docs/terraform.tf new file mode 100644 index 00000000000..f63d7746436 --- /dev/null +++ b/demo/kitchen-sink/docs/terraform.tf @@ -0,0 +1,94 @@ +export TF_LOG=TRACE + +# An AMI +variable "ami" { + description = "the AMI to use" +} + +/* A multi + line comment. */ +resource "aws_instance" "web" { + ami = "${var.ami}" + count = 2 + source_dest_check = false + + connection { + user = "root" + } +} + +resource "aws_instance" "web" { + subnet = "${var.env == "production" ? var.prod_subnet : var.dev_subnet}" +} + +variable "count" { + default = 2 +} + +variable "hostnames" { + default = { + "0" = "example1.org" + "1" = "example2.net" + } +} + +data "template_file" "web_init" { + # Render the template once for each instance + count = "${length(var.hostnames)}" + template = "${file("templates/web_init.tpl")}" + vars { + # count.index tells us the index of the instance we are rendering + hostname = "${var.hostnames[count.index]}" + } +} + +resource "aws_instance" "web" { + # Create one instance for each hostname + count = "${length(var.hostnames)}" + + # Pass each instance its corresponding template_file + user_data = "${data.template_file.web_init.*.rendered[count.index]}" +} + +variable "count" { + default = 2 +} + +# Define the common tags for all resources +locals { + common_tags = { + Component = "awesome-app" + Environment = "production" + } +} + +# Create a resource that blends the common tags with instance-specific tags. +resource "aws_instance" "server" { + ami = "ami-123456" + instance_type = "t2.micro" + + tags = "${merge( + local.common_tags, + map( + "Name", "awesome-app-server", + "Role", "server" + ) + )}" +} + +$ terraform apply -var foo=bar -var foo=baz +$ terraform apply -var 'foo={quux="bar"}' -var 'foo={bar="baz"}' + +$ terraform apply -var-file=foo.tfvars -var-file=bar.tfvars +$ TF_VAR_somemap='{foo = "bar", baz = "qux"}' terraform plan + +resource "aws_instance" "web" { + # ... + + count = "${var.count}" + + # Tag the instance with a counter starting at 1, ie. web-001 + tags { + Name = "${format("web-%03d", count.index + 1)}" + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/text.txt b/demo/kitchen-sink/docs/text.txt new file mode 100644 index 00000000000..991a5d70146 --- /dev/null +++ b/demo/kitchen-sink/docs/text.txt @@ -0,0 +1,9 @@ +This is just some text! + +// These + # are + -- not + + (but indent actions work) + +This is just some text! diff --git a/demo/kitchen-sink/docs/tsv.tsv b/demo/kitchen-sink/docs/tsv.tsv new file mode 100644 index 00000000000..f5f9b1c0336 --- /dev/null +++ b/demo/kitchen-sink/docs/tsv.tsv @@ -0,0 +1,15 @@ +col1 col2 long col3 col4 +"col1 with quotes" col2 col3 col4 +col1 col2 col"""3 co""l4 +col1 col2 col3"broken" col4 +col1" -"col2 col3 col4 col5 +col1 "col2 +multiline" "col3 +multiline""string +3" "col4 +multiline string + +4" +col1 col2 "c o l""3" col4 col5 col6 col7 col8 col9 col10 col11 col12 col13 +col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13 +col1 col2 col3 col4 col5 col6 co"l7 col8 col9 col10 11 col12 col13 diff --git a/demo/kitchen-sink/docs/vbscript.vbs b/demo/kitchen-sink/docs/vbscript.vbs index ace5c9f9c71..76a10570d45 100644 --- a/demo/kitchen-sink/docs/vbscript.vbs +++ b/demo/kitchen-sink/docs/vbscript.vbs @@ -1,23 +1,23 @@ -myfilename = "C:\Wikipedia - VBScript - Example - Hello World.txt" -MakeHelloWorldFile myfilename - -Sub MakeHelloWorldFile (FileName) -'Create a new file in C: drive or overwrite existing file - Set FSO = CreateObject("Scripting.FileSystemObject") - If FSO.FileExists(FileName) Then - Answer = MsgBox ("File " & FileName & " exists ... OK to overwrite?", vbOKCancel) - 'If button selected is not OK, then quit now - 'vbOK is a language constant - If Answer <> vbOK Then Exit Sub - Else - 'Confirm OK to create - Answer = MsgBox ("File " & FileName & " ... OK to create?", vbOKCancel) - If Answer <> vbOK Then Exit Sub - End If - 'Create new file (or replace an existing file) - Set FileObject = FSO.CreateTextFile (FileName) - FileObject.WriteLine "Time ... " & Now() - FileObject.WriteLine "Hello World" - FileObject.Close() - MsgBox "File " & FileName & " ... updated." +myfilename = "C:\Wikipedia - VBScript - Example - Hello World.txt" +MakeHelloWorldFile myfilename + +Sub MakeHelloWorldFile (FileName) + 'Create a new file in C: drive or overwrite existing file + Set FSO = CreateObject("Scripting.FileSystemObject") + If FSO.FileExists(FileName) Then + Answer = MsgBox ("File " & FileName & " exists ... OK to overwrite?", vbOKCancel) + 'If button selected is not OK, then quit now + 'vbOK is a language constant + If Answer <> vbOK Then Exit Sub + Else + 'Confirm OK to create + Answer = MsgBox ("File " & FileName & " ... OK to create?", vbOKCancel) + If Answer <> vbOK Then Exit Sub + End If + 'Create new file (or replace an existing file) + Set FileObject = FSO.CreateTextFile (FileName) + FileObject.WriteLine "Time ... " & Now() + FileObject.WriteLine "Hello World" + FileObject.Close() + MsgBox "File " & FileName & " ... updated." End Sub \ No newline at end of file diff --git a/demo/kitchen-sink/docs/vhdl.vhd b/demo/kitchen-sink/docs/vhdl.vhd index 662375e8b6c..5854737a681 100644 --- a/demo/kitchen-sink/docs/vhdl.vhd +++ b/demo/kitchen-sink/docs/vhdl.vhd @@ -1,5 +1,5 @@ -library IEEE -user IEEE.std_logic_1164.all; +library IEEE; +use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity COUNT16 is @@ -14,7 +14,7 @@ entity COUNT16 is end entity; architecture count_rtl of COUNT16 is - signal count :std_logic_vector (15 downto 0); + signal count : unsigned (15 downto 0); begin process (clk, rst) begin @@ -28,7 +28,7 @@ begin end if; end process; - cOut <= count; + cOut <= std_logic_vector(count); end architecture; - \ No newline at end of file + diff --git a/demo/kitchen-sink/docs/visualforce.vfp b/demo/kitchen-sink/docs/visualforce.vfp new file mode 100644 index 00000000000..862014b094e --- /dev/null +++ b/demo/kitchen-sink/docs/visualforce.vfp @@ -0,0 +1,18 @@ + + + + + + + + + + +{!IF(AND(Price < 1, Quantity < 1), "Small", null)} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/vue.vue b/demo/kitchen-sink/docs/vue.vue new file mode 100644 index 00000000000..b1ff66bbc67 --- /dev/null +++ b/demo/kitchen-sink/docs/vue.vue @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + diff --git a/demo/kitchen-sink/docs/yaml.yaml b/demo/kitchen-sink/docs/yaml.yaml index 52ee320e6a1..e8747db791d 100644 --- a/demo/kitchen-sink/docs/yaml.yaml +++ b/demo/kitchen-sink/docs/yaml.yaml @@ -18,6 +18,7 @@ items: size: 8 price: 100.27 quantity: 1 + version: 1.2.3.4 bill-to: &id001 street: | diff --git a/demo/kitchen-sink/docs/zeek.zeek b/demo/kitchen-sink/docs/zeek.zeek new file mode 100644 index 00000000000..a4c4bb7c50e --- /dev/null +++ b/demo/kitchen-sink/docs/zeek.zeek @@ -0,0 +1,179 @@ +# An example of the Zeek scripting language. + +##! A Zeekygen-style summmary comment. + +# TODO: just an example of a todo-indicator + +@load base/frameworks/notice + +@if ( F ) +@endif + +module Example; + +export { + + type SimpleEnum: enum { ONE, TWO, THREE }; + + redef enum SimpleEnum += { + + ## A Zeekygen-style comment. + FOUR, + FIVE, ##< A Zeekygen-style comment. + }; + + type SimpleRecord: record { + field1: count; + field2: bool; + } &redef; + + redef record SimpleRecord += { + + field3: string &optional; + + field4: string &default="blah"; + }; + + const init_option: bool = T; + + option runtime_option: bool = F; + + global test_opaque: opaque of md5; + + global test_vector: vector of count; + + global myfunction: function(msg: string, c: count &default=0): count; + + global myhook: hook(tag: string); + + global myevent: event(tag: string); +} + +function myfunction(msg: string, c: count): count + { + print "in myfunction", msg, c; + return 0; + } + +event myevent(msg: string) &priority=1 + { + print "in myevent"; + } + +hook myhook(msg: string) + { + print "in myevent"; + } + +event zeek_init() + { + local b = T; + local s = "\xff\xaf\"and more after the escaped quote"; + local p = /foo|bar\xbe\/and more after the escaped slash/; + local c = 10; + + local sr = SimpleRecord($field1 = 0, $field2 = T, $field3 = "hi"); + + print sr?$field3, sr$field1; + + local myset: set[string] = set("one", "two", "three"); + + add myset["four"]; + delete myset["one"]; + + for ( ms in myset ) + { + print ms is string, s as string; + + print s[1:3]; + + local tern: count = s == "two" ? 2 : 0; + + if ( s !in myset ) + print fmt("error %4.2f: %s", 3.14159, "wtf?"); + } + + switch ( c ) { + case 1: + break; + case 2: + fallthrough; + default: + break; + } + + if ( ! b ) + print "here"; + else + print "there"; + + while ( c != 0 ) + { + if ( c >= 5 ) + c += 0; + else if ( c == 8 ) + c -= 0; + + c = c / 1; + c = c / 1; + c = c - 1; + } + + print |myset|; + print ~5; + print 1 & 0xff; + print 2 ^ 5; + + myfunction("hello function"); + hook myhook("hell hook"); + event myevent("hello event"); + schedule 1sec { myevent("hello scheduled event") }; + + print 0, 7; + print 0xff, 0xdeadbeef; + + print 3.14159; + print 1234.0; + print 1234e0; + print .003E-23; + print .003E+23; + + print 123/udp; + print 8000/tcp; + print 13/icmp; + print 42/unknown; + + print google.com; + print 192.168.50.1; + print 255.255.255.255; + print 0.0.0.0; + + print 10.0.0.0/16; + + print [2001:0db8:85a3:0000:0000:8a2e:0370:7334]; + # test for case insensitivity + print [2001:0DB8:85A3:0000:0000:8A2E:0370:7334]; + # any case mixture is allowed + print [2001:0dB8:85a3:0000:0000:8A2E:0370:7334]; + # leading zeroes of a 16-bit group may be omitted + print [2001:db8:85a3:0:0:8a2e:370:7334]; + # a single occurrence of consecutive groups of zeroes may be replaced by :: + print [2001:db8:85a3::8a2e:370:7334]; + # all zeroes should work + print [0:0:0:0:0:0:0:0]; + # all zeroes condensed should work + print [::]; + # hybrid ipv6-ipv4 address should work + print [2001:db8:0:0:0:FFFF:192.168.0.5]; + # hybrid ipv6-ipv4 address with zero ommission should work + print [2001:db8::FFFF:192.168.0.5]; + + print [2001:0db8:85a3:0000:0000:8a2e:0370:7334]/64; + + print 1day, 1days, 1.0day, 1.0days; + print 1hr, 1hrs, 1.0hr, 1.0hrs; + print 1min, 1mins, 1.0min, 1.0mins; + print 1sec, 1secs, 1.0sec, 1.0secs; + print 1msec, 1msecs, 1.0msec, 1.0msecs; + print 1usec, 1usecs, 1.0usec, 1.0usecs; + } diff --git a/demo/kitchen-sink/docs/zig.zig b/demo/kitchen-sink/docs/zig.zig new file mode 100644 index 00000000000..8d1d83187c0 --- /dev/null +++ b/demo/kitchen-sink/docs/zig.zig @@ -0,0 +1,6 @@ +const std = @import("std"); + +pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + try stdout.print("Hello, {s}!\n", .{"world"}); +} \ No newline at end of file diff --git a/demo/kitchen-sink/file_drop.js b/demo/kitchen-sink/file_drop.js index 8b89d5f1f2c..0b768af3e53 100644 --- a/demo/kitchen-sink/file_drop.js +++ b/demo/kitchen-sink/file_drop.js @@ -1,35 +1,3 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - var config = require("ace/config"); var event = require("ace/lib/event"); var modelist = require("ace/ext/modelist"); @@ -69,5 +37,3 @@ config.defineOptions(Editor.prototype, "editor", { value: true } }); - -}); \ No newline at end of file diff --git a/demo/kitchen-sink/inline_editor.js b/demo/kitchen-sink/inline_editor.js index 6b56887dbf6..ec1b6d9bfab 100644 --- a/demo/kitchen-sink/inline_editor.js +++ b/demo/kitchen-sink/inline_editor.js @@ -1,35 +1,3 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - - -define(function(require, exports, module) { "use strict"; var LineWidgets = require("ace/line_widgets").LineWidgets; @@ -99,4 +67,3 @@ require("ace/commands/default_commands").commands.push({ inlineEditor.setTheme("ace/theme/solarized_light"); } }); -}); diff --git a/demo/kitchen-sink/layout.js b/demo/kitchen-sink/layout.js index 1332eef3e57..0959325581e 100644 --- a/demo/kitchen-sink/layout.js +++ b/demo/kitchen-sink/layout.js @@ -1,5 +1,3 @@ - -define(function(require, exports, module) { "use strict"; var dom = require("ace/lib/dom"); @@ -125,8 +123,3 @@ exports.singleLineEditor = function(el) { return editor; }; - - - -}); - diff --git a/demo/kitchen-sink/require.js b/demo/kitchen-sink/require.js index 203843c1b75..5c5e56cfaae 100644 --- a/demo/kitchen-sink/require.js +++ b/demo/kitchen-sink/require.js @@ -1,2074 +1,648 @@ -/** vim: et:ts=4:sw=4:sts=4 - * @license RequireJS 2.1.11+ Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/requirejs for details +/* eslint-env browser */ +/* global importScripts Response Request */ + +/** + * requirejs compatible loader for cloud9 + * + * supports the following loaders + * require("text!./path.md") - load a file as text + * require("json!./file.json") - load a file as json + * require("asset-url!./directory-or-a-file") - get a url for a image, html or audio file or + * a whole directory, files required this way are copied to the cdn without modifications + * require("webworker!./modulname") - get a url that can be used to start a webworker + * require("webworker!!./modulname") - get a url for webworker, and include all the + * instances of require("!./modulname") in a bundle for that worker + * require("language!./modulname") - the commonly used tagname for language worker + * require("vfs!./module") - bundles js file with it's dependencies in a way that can be used + * on vfs worker, either as a vfs extension or a standalone executable + * require("architect!./modulname") - wraps module in a function allowing + * delayed initialization of architect plugins + * TODO: + * require("glob!./ace/mode/*(:-_test|_highlight_rules).js").load("css", function() {}) - + * require("lazy!./module").load(function() {}) - */ -//Not using strict: uneven strict support in browsers, #392, and causes -//problems with requirejs.exec()/transpiler plugins that may not be strict. -/*jslint regexp: true, nomen: true, sloppy: true */ -/*global window, navigator, document, importScripts, setTimeout, opera */ - -var requirejs, require, define; -(function (global) { - var req, s, head, baseElement, dataMain, src, - interactiveScript, currentlyAddingScript, mainScript, subPath, - version = '2.1.11+', - commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, - cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, - jsSuffixRegExp = /\.js$/, - currDirRegExp = /^\.\//, - op = Object.prototype, - ostring = op.toString, - hasOwn = op.hasOwnProperty, - ap = Array.prototype, - apsp = ap.splice, - isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), - isWebWorker = !isBrowser && typeof importScripts !== 'undefined', - //PS3 indicates loaded and complete, but need to wait for complete - //specifically. Sequence is 'loading', 'loaded', execution, - // then 'complete'. The UA check is unfortunate, but not sure how - //to feature test w/o causing perf issues. - readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? - /^complete$/ : /^(complete|loaded)$/, - defContextName = '_', - //Oh the tragedy, detecting opera. See the usage of isOpera for reason. - isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', - contexts = {}, - cfg = {}, - globalDefQueue = [], - useInteractive = false; - - function isFunction(it) { - return ostring.call(it) === '[object Function]'; - } - - function isArray(it) { - return ostring.call(it) === '[object Array]'; - } - - /** - * Helper function for iterating over an array. If the func returns - * a true value, it will break out of the loop. - */ - function each(ary, func) { - if (ary) { - var i; - for (i = 0; i < ary.length; i += 1) { - if (ary[i] && func(ary[i], i, ary)) { - break; - } - } +(function() { + var global = (function() { + return this; + })(); + if (!global && typeof window != "undefined") global = window; // can happen in strict mode + if (!global && typeof self != "undefined") global = self; // can happen in webworker + + var commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$|`([^`\\]|\\.)*`)/gm; + var cjsRequireRegExp = /require\s*\(\s*["']([^'"\s]+)["']\s*\)/g; + + function getInlineDeps(fn) { + var deps = []; + if (fn.length) { + fn + .toString() + .replace(commentRegExp, "") + .replace(cjsRequireRegExp, function(match, dep, index, str) { + var i = index; + while (str.charCodeAt((i -= 1)) <= 32) {} + if (str.charAt(i) !== ".") deps.push(dep); + }); + deps = ["require", "exports", "module"].concat(deps); } + return deps; } - /** - * Helper function for iterating over an array backwards. If the func - * returns a true value, it will break out of the loop. - */ - function eachReverse(ary, func) { - if (ary) { - var i; - for (i = ary.length - 1; i > -1; i -= 1) { - if (ary[i] && func(ary[i], i, ary)) { - break; - } - } + var define = function(name, deps, callback) { + // Allow for anonymous modules + if (typeof name !== "string") { + callback = deps; + deps = name; + name = null; } - } - - function hasProp(obj, prop) { - return hasOwn.call(obj, prop); - } - - function getOwn(obj, prop) { - return hasProp(obj, prop) && obj[prop]; - } - - /** - * Cycles over properties in an object and calls a function for each - * property value. If the function returns a truthy value, then the - * iteration is stopped. - */ - function eachProp(obj, func) { - var prop; - for (prop in obj) { - if (hasProp(obj, prop)) { - if (func(obj[prop], prop)) { - break; - } - } + // This module may not have dependencies + if (deps && !Array.isArray(deps)) { + callback = deps; + deps = null; } - } - - /** - * Simple function to mix in properties from source into target, - * but only if target does not already have a property of the same name. - */ - function mixin(target, source, force, deepStringMixin) { - if (source) { - eachProp(source, function (value, prop) { - if (force || !hasProp(target, prop)) { - if (deepStringMixin && typeof value === 'object' && value && - !isArray(value) && !isFunction(value) && - !(value instanceof RegExp)) { - if (!target[prop]) { - target[prop] = {}; - } - mixin(target[prop], value, force, deepStringMixin); - } else { - target[prop] = value; - } - } - }); + if (nextModule) { + if (!name || name == nextModule.name) { + name = nextModule.name; + deps = deps || nextModule.deps; + nextModule = null; + } } - return target; - } - //Similar to Function.prototype.bind, but the 'this' object is specified - //first, since it is easier to read/figure out what 'this' will be. - function bind(obj, fn) { - return function () { - return fn.apply(obj, arguments); - }; - } + if (!name) return defQueue.push([deps, callback]); - function scripts() { - return document.getElementsByTagName('script'); - } + if (define.loaded[name]) return; - function defaultOnError(err) { - throw err; - } + if (!deps && typeof callback == "function") deps = getInlineDeps(callback); - //Allow getting a global that is expressed in - //dot notation, like 'a.b.c'. - function getGlobal(value) { - if (!value) { - return value; - } - var g = global; - each(value.split('.'), function (part) { - g = g[part]; + define.loaded[name] = { + id: name, + deps: normalizeNames(name, deps || []), + factory: callback, + exports: {}, + packaged: true, + }; + if (define.loading[name]) delete define.loading[name]; + if (define.lastModule) define.pending.push(name); + else define.lastModule = name; + }; + var defQueue = []; + var nextModule; + var addToLoadQueue = function(missing, deps, callback, errback) { + var toLoad = missing.length; + var map = {}; + define.queue.push({ + deps: deps, + map: map, + toLoad: toLoad, + callback: callback, + errback: errback, }); - return g; - } - - /** - * Constructs an error with a pointer to an URL with more information. - * @param {String} id the error ID that maps to an ID on a web page. - * @param {String} message human readable error. - * @param {Error} [err] the original error, if there is one. - * - * @returns {Error} - */ - function makeError(id, msg, err, requireModules) { - var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); - e.requireType = id; - e.requireModules = requireModules; - if (err) { - e.originalError = err; - } - return e; - } - if (typeof define !== 'undefined') { - //If a define is already in play via another AMD loader, - //do not overwrite. - return; - } - - if (typeof requirejs !== 'undefined') { - if (isFunction(requirejs)) { - //Do not overwrite an existing requirejs instance. - return; - } - cfg = requirejs; - requirejs = undefined; - } - - //Allow for a require config object - if (typeof require !== 'undefined' && !isFunction(require)) { - //assume it is a config object. - cfg = require; - require = undefined; - } - - function newContext(contextName) { - var inCheckLoaded, Module, context, handlers, - checkLoadedTimeoutId, - config = { - //Defaults. Do not set a default for map - //config to speed up normalize(), which - //will run faster if there is no default. - waitSeconds: 7, - baseUrl: './', - paths: {}, - bundles: {}, - pkgs: {}, - shim: {}, - config: {} - }, - registry = {}, - //registry of just enabled modules, to speed - //cycle breaking code when lots of modules - //are registered, but not activated. - enabledRegistry = {}, - undefEvents = {}, - defQueue = [], - defined = {}, - urlFetched = {}, - bundlesMap = {}, - requireCounter = 1, - unnormalizedCounter = 1; - - /** - * Trims the . and .. from an array of path segments. - * It will keep a leading path segment if a .. will become - * the first path segment, to help with module name lookups, - * which act like paths, but can be remapped. But the end result, - * all paths that use this function should look normalized. - * NOTE: this method MODIFIES the input array. - * @param {Array} ary the array of path segments. - */ - function trimDots(ary) { - var i, part, length = ary.length; - for (i = 0; i < length; i++) { - part = ary[i]; - if (part === '.') { - ary.splice(i, 1); - i -= 1; - } else if (part === '..') { - if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { - //End of the line. Keep at least one non-dot - //path segment at the front so it can be mapped - //correctly to disk. Otherwise, there is likely - //no path mapping for a path starting with '..'. - //This can still fail, but catches the most reasonable - //uses of .. - break; - } else if (i > 0) { - ary.splice(i - 1, 2); - i -= 2; - } - } + for (var i = 0; i < missing.length; ++i) { + var p = missing[i]; + map[p] = 1; + if (!define.loading[p]) { + define.loading[p] = 1; + require.load(p); } } + }; - /** - * Given a relative module name, like ./something, normalize it to - * a real name that can be mapped to a path. - * @param {String} name the relative name - * @param {String} baseName a real name that the name arg is relative - * to. - * @param {Boolean} applyMap apply the map config to the value. Should - * only be done if this normalization is for a dependency ID. - * @returns {String} normalized name - */ - function normalize(name, baseName, applyMap) { - var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex, - foundMap, foundI, foundStarMap, starI, - baseParts = baseName && baseName.split('/'), - normalizedBaseParts = baseParts, - map = config.map, - starMap = map && map['*']; - - //Adjust any relative paths. - if (name && name.charAt(0) === '.') { - //If have a base name, try to normalize against it, - //otherwise, assume it is a top-level require that will - //be relative to baseUrl in the end. - if (baseName) { - //Convert baseName to array, and lop off the last part, - //so that . matches that 'directory' and not name of the baseName's - //module. For instance, baseName of 'one/two/three', maps to - //'one/two/three.js', but we want the directory, 'one/two' for - //this normalization. - normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); - name = name.split('/'); - lastIndex = name.length - 1; - - // If wanting node ID compatibility, strip .js from end - // of IDs. Have to do this here, and not in nameToUrl - // because node allows either .js or non .js to map - // to same file. - if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { - name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); - } - - name = normalizedBaseParts.concat(name); - trimDots(name); - name = name.join('/'); - } else if (name.indexOf('./') === 0) { - // No baseName, so this is ID is resolved relative - // to baseUrl, pull off the leading dot. - name = name.substring(2); - } - } - - //Apply map config if available. - if (applyMap && map && (baseParts || starMap)) { - nameParts = name.split('/'); - - outerLoop: for (i = nameParts.length; i > 0; i -= 1) { - nameSegment = nameParts.slice(0, i).join('/'); - - if (baseParts) { - //Find the longest baseName segment match in the config. - //So, do joins on the biggest to smallest lengths of baseParts. - for (j = baseParts.length; j > 0; j -= 1) { - mapValue = getOwn(map, baseParts.slice(0, j).join('/')); - - //baseName segment has config, find if it has one for - //this name. - if (mapValue) { - mapValue = getOwn(mapValue, nameSegment); - if (mapValue) { - //Match, update name to the new value. - foundMap = mapValue; - foundI = i; - break outerLoop; - } - } - } - } - - //Check for a star map match, but just hold on to it, - //if there is a shorter segment match later in a matching - //config, then favor over this star map. - if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { - foundStarMap = getOwn(starMap, nameSegment); - starI = i; - } - } - - if (!foundMap && foundStarMap) { - foundMap = foundStarMap; - foundI = starI; + var processLoadQueue = function(err, id) { + var changed = false; + if (err) { + if (!id) id = err.id; + define.errors[id] = err; + define.queue.forEach(function(r) { + if (r.map[id]) { + r.toLoad = -1; + if (r.errback) r.errback(err); } - - if (foundMap) { - nameParts.splice(0, foundI, foundMap); - name = nameParts.join('/'); + }); + if (define.lastModule == id) define.lastModule = null; + define.pending = define.pending.filter(function(p) { + return p != id; + }); + changed = true; + err.from = []; + for (var i in define.loaded) { + var index = define.loaded[i].deps.indexOf(id); + if (index != -1) { + err.from.push(define.loaded[i].id); } } - - // If the name points to a package's name, use - // the package main instead. - pkgMain = getOwn(config.pkgs, name); - - return pkgMain ? pkgMain : name; + console.error("Error loading " + id + " required from " + err.from.slice(0, 2)); + } else if (id && !defQueue.length && !define.loaded[id]) { + // the script didn't call define + defQueue = [(config.shim && config.shim[id]) || [[], null]]; } - function removeScript(name) { - if (isBrowser) { - each(scripts(), function (scriptNode) { - if (scriptNode.getAttribute('data-requiremodule') === name && - scriptNode.getAttribute('data-requirecontext') === context.contextName) { - scriptNode.parentNode.removeChild(scriptNode); - return true; - } - }); - } + if (defQueue.length) { + if (defQueue.length > 1) throw new Error("more than one module in defqueue"); + define(id, defQueue[0][0], defQueue[0][1]); + defQueue.length = 0; } - function hasPathFallback(id) { - var pathConfig = getOwn(config.paths, id); - if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { - //Pop off the first array value, since it failed, and - //retry - pathConfig.shift(); - context.require.undef(id); - - //Custom require that does not do map translation, since - //ID is "absolute", already mapped/resolved. - context.makeRequire(null, { - skipMap: true - })([id]); - - return true; + var pending = define.pending; + define.queue.forEach(function(r) { + pending.forEach(function(id) { + if (r.map[id]) r.toLoad--; + }); + if (r.map[define.lastModule]) r.toLoad--; + if (!r.toLoad) { + changed = true; + _require("", r.deps, r.callback, r.errback); } - } + }); - //Turns a plugin!resource to [plugin, resource] - //with the plugin being undefined if the name - //did not have a plugin prefix. - function splitPrefix(name) { - var prefix, - index = name ? name.indexOf('!') : -1; - if (index > -1) { - prefix = name.substring(0, index); - name = name.substring(index + 1, name.length); - } - return [prefix, name]; + define.lastModule = null; + if (pending.length) define.pending = []; + + if (changed) { + define.queue = define.queue.filter(function(r) { + return r.toLoad > 0; + }); } + }; - /** - * Creates a module mapping that includes plugin prefix, module - * name, and path. If parentModuleMap is provided it will - * also normalize the name via require.normalize() - * - * @param {String} name the module name - * @param {String} [parentModuleMap] parent module map - * for the module name, used to resolve relative names. - * @param {Boolean} isNormalized: is the ID already normalized. - * This is true if this call is done for a define() module ID. - * @param {Boolean} applyMap: apply the map config to the ID. - * Should only be true if this map is for a dependency. - * - * @returns {Object} - */ - function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { - var url, pluginModule, suffix, nameParts, - prefix = null, - parentName = parentModuleMap ? parentModuleMap.name : null, - originalName = name, - isDefine = true, - normalizedName = ''; + define.amd = {}; + define.queue = []; + define.loaded = {}; + define.errors = {}; + define.loading = {}; + define.pending = []; + define.modules = {require: 1, exports: 1, module: 1}; + define.fetchedUrls = {}; + + var activateModule = function(name) { + var module = define.loaded[name]; + var exports = module.exports; + if (typeof module.factory !== "function") { + exports = module.factory; + } else { + var req = function(path, callback) { + return _require(name, path, callback); + }; + req.config = config; + req.toUrl = function(id) { + return require.toUrl(id); + }; - //If no name, then it means it is a require call, generate an - //internal name. - if (!name) { - isDefine = false; - name = '_@r' + (requireCounter += 1); - } + var missing = checkMissing(module.deps); + if (missing.length) return missing; - nameParts = splitPrefix(name); - prefix = nameParts[0]; - name = nameParts[1]; + module.define = define; + var specialModules = { + require: req, + exports: exports, + module: module, + }; - if (prefix) { - prefix = normalize(prefix, parentName, applyMap); - pluginModule = getOwn(defined, prefix); + if (name.lastIndexOf("architect!", 0) == 0 && !module.pluginFactory) { + module.pluginFactory = module.factory; + module.factory = activateArchitectModule; } - //Account for relative paths if there is a base name. - if (name) { - if (prefix) { - if (pluginModule && pluginModule.normalize) { - //Plugin is loaded, use its normalize method. - normalizedName = pluginModule.normalize(name, function (name) { - return normalize(name, parentName, applyMap); - }); - } else { - normalizedName = normalize(name, parentName, applyMap); - } - } else { - //A regular module. - normalizedName = normalize(name, parentName, applyMap); + define.modules[name] = exports; + var args = module.deps.slice(0, module.factory.length); + var returnValue = args.length + ? module.factory.apply( + module, + args.map(function(name) { + return specialModules[name] || lookup(name); + }) + ) + : module.factory(req, exports, module); - //Normalized name may be a plugin ID due to map config - //application in normalize. The map config values must - //already be normalized, so do not need to redo that part. - nameParts = splitPrefix(normalizedName); - prefix = nameParts[0]; - normalizedName = nameParts[1]; - isNormalized = true; + exports = returnValue == undefined ? module.exports : returnValue; + } + if (!config.$keepLoaders) delete define.loaded[name]; + define.modules[name] = exports; + }; - url = context.nameToUrl(normalizedName); + var checkMissing = function(deps, seen, missing) { + missing = missing || {}; + seen = seen || {}; + for (var i = 0; i < deps.length; ++i) { + var depName = deps[i]; + if (!define.modules[depName]) { + var dep = define.loaded[depName]; + if (!dep) missing[depName] = 1; + else if (!missing[depName] && !seen[depName]) { + seen[depName] = 1; + checkMissing(dep.deps, seen, missing); } } - - //If the id is a plugin id that cannot be determined if it needs - //normalization, stamp it with a unique ID so two matching relative - //ids that may conflict can be separate. - suffix = prefix && !pluginModule && !isNormalized ? - '_unnormalized' + (unnormalizedCounter += 1) : - ''; - - return { - prefix: prefix, - name: normalizedName, - parentMap: parentModuleMap, - unnormalized: !!suffix, - url: url, - originalName: originalName, - isDefine: isDefine, - id: (prefix ? - prefix + '!' + normalizedName : - normalizedName) + suffix - }; } + return Object.keys(missing); + }; - function getModule(depMap) { - var id = depMap.id, - mod = getOwn(registry, id); - - if (!mod) { - mod = registry[id] = new context.Module(depMap); - } - - return mod; + var lookup = function(moduleName) { + var mod = define.modules[moduleName]; + if (mod === undefined && define.loaded[moduleName]) { + activateModule(moduleName); + mod = define.modules[moduleName]; } + return mod; + }; - function on(depMap, name, fn) { - var id = depMap.id, - mod = getOwn(registry, id); - - if (hasProp(defined, id) && - (!mod || mod.defineEmitComplete)) { - if (name === 'defined') { - fn(defined[id]); - } + var _require = function(parentId, moduleName, callback, errback) { + if (typeof moduleName === "string") { + var depName = normalizeName(parentId, moduleName); + var module = lookup(depName); + if (module !== undefined) { + if (typeof callback == "function") callback(module); + return module; + } else if (typeof importScripts != "undefined" || syncLoaders.test(moduleName)) { + addToLoadQueue([depName], [depName]); + return lookup(depName); + } + } else if (Array.isArray(moduleName)) { + var deps = normalizeNames(parentId, moduleName); + var missing = checkMissing(deps); + if (!missing.length) { + var args = deps.map(lookup); + return callback && callback.apply(null, args); } else { - mod = getModule(depMap); - if (mod.error && name === 'error') { - fn(mod.error); - } else { - mod.on(name, fn); - } - } - } - - function onError(err, errback) { - var ids = err.requireModules, - notified = false; - - if (errback) { - errback(err); - } else { - each(ids, function (id) { - var mod = getOwn(registry, id); - if (mod) { - //Set error on module, so it skips timeout checks. - mod.error = err; - if (mod.events.error) { - notified = true; - mod.emit('error', err); - } - } - }); - - if (!notified) { - req.onError(err); - } + return addToLoadQueue(missing, deps, callback, errback); } } + }; - /** - * Internal method to transfer globalQueue items to this context's - * defQueue. - */ - function takeGlobalQueue() { - //Push all the globalDefQueue items into the context's defQueue - if (globalDefQueue.length) { - //Array splice in the values since the context code has a - //local var ref to defQueue, so cannot just reassign the one - //on context. - apsp.apply(defQueue, - [defQueue.length, 0].concat(globalDefQueue)); - globalDefQueue = []; - } + var normalizeName = function(parentId, moduleName) { + if (/!/.test(parentId)) parentId = parentId.split("!").pop(); + // normalize plugin requires + var i = moduleName.indexOf("!"); + if (i !== -1) { + return ( + normalizeName(parentId, moduleName.slice(0, i)) + + "!" + + normalizeName(parentId, moduleName.slice(i + 1)) + ); } - - handlers = { - 'require': function (mod) { - if (mod.require) { - return mod.require; - } else { - return (mod.require = context.makeRequire(mod.map)); - } - }, - 'exports': function (mod) { - mod.usingExports = true; - if (mod.map.isDefine) { - if (mod.exports) { - return (defined[mod.map.id] = mod.exports); - } else { - return (mod.exports = defined[mod.map.id] = {}); - } - } - }, - 'module': function (mod) { - if (mod.module) { - return mod.module; - } else { - return (mod.module = { - id: mod.map.id, - uri: mod.map.url, - config: function () { - return getOwn(config.config, mod.map.id) || {}; - }, - exports: mod.exports || (mod.exports = {}) - }); - } + // normalize relative requires + if (moduleName.charAt(0) == ".") { + var parentChunks = parentId.split("/"); + var parentModule = parentChunks.shift(); + if (parentModule.charAt(0) == "@") { + parentModule = parentModule + "/" + parentChunks.shift(); } - }; - - function cleanRegistry(id) { - //Clean up machinery used for waiting modules. - delete registry[id]; - delete enabledRegistry[id]; - } - - function breakCycle(mod, traced, processed) { - var id = mod.map.id; - if (mod.error) { - mod.emit('error', mod.error); - } else { - traced[id] = true; - each(mod.depMaps, function (depMap, i) { - var depId = depMap.id, - dep = getOwn(registry, depId); + var path = parentChunks.slice(0, -1).join("/"); + moduleName = parentModule + (path ? "/" + path : "") + "/" + moduleName; - //Only force things that have not completed - //being defined, so still in the registry, - //and only if it has not been matched up - //in the module already. - if (dep && !mod.depMatched[i] && !processed[depId]) { - if (getOwn(traced, depId)) { - mod.defineDep(i, defined[depId]); - mod.check(); //pass false? - } else { - breakCycle(dep, traced, processed); - } - } - }); - processed[id] = true; + while (moduleName.indexOf(".") !== -1 && previous != moduleName) { + var previous = moduleName; + moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); } } - function checkLoaded() { - var err, usingPathFallback, - waitInterval = config.waitSeconds * 1000, - //It is possible to disable the wait interval by using waitSeconds of 0. - expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), - noLoads = [], - reqCalls = [], - stillLoading = false, - needCycleCheck = true; - - //Do not bother if this call was a result of a cycle break. - if (inCheckLoaded) { - return; - } + return moduleName; + }; - inCheckLoaded = true; + var normalizeNames = function(parentId, moduleNames) { + return moduleNames.map(function(name) { + return normalizeName(parentId, name); + }); + }; - //Figure out the state of all the modules. - eachProp(enabledRegistry, function (mod) { - var map = mod.map, - modId = map.id; + var require = function(module, callback, errback) { + return _require("", module, callback, errback); + }; - //Skip things that are not enabled or in error state. - if (!mod.enabled) { - return; - } + var config = (require.config = function(cfg) { + if (cfg.baseUrl) config.baseUrl = cfg.baseUrl.replace(/\/*$/, "/"); - if (!map.isDefine) { - reqCalls.push(mod); - } + if (cfg.host) host = cfg.host; - if (!mod.error) { - //If the module should be executed, and it has not - //been inited and time is up, remember it. - if (!mod.inited && expired) { - if (hasPathFallback(modId)) { - usingPathFallback = true; - stillLoading = true; - } else { - noLoads.push(modId); - removeScript(modId); - } - } else if (!mod.inited && mod.fetched && map.isDefine) { - stillLoading = true; - if (!map.prefix) { - //No reason to keep looking for unfinished - //loading. If the only stillLoading is a - //plugin resource though, keep going, - //because it may be that a plugin resource - //is waiting on a non-plugin cycle. - return (needCycleCheck = false); - } - } - } + if (Array.isArray(cfg.packages)) { + cfg.packages.forEach(function(pkg) { + if (typeof pkg === "string") pkg = {name: pkg}; + config.packages[pkg.name] = { + name: pkg.name, + location: (pkg.location || pkg.name).replace(/\/*$/, "/"), + main: (pkg.main || "main").replace(/\.js$/, "").replace(/^\.\//, ""), + }; }); - - if (expired && noLoads.length) { - //If wait time expired, throw error of unloaded modules. - err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); - err.contextName = context.contextName; - return onError(err); - } - - //Not expired, check for a cycle. - if (needCycleCheck) { - each(reqCalls, function (mod) { - breakCycle(mod, {}, {}); - }); - } - - //If still waiting on loads, and the waiting load is something - //other than a plugin resource, or there are still outstanding - //scripts, then just try back later. - if ((!expired || usingPathFallback) && stillLoading) { - //Something is still waiting to load. Wait for it, but only - //if a timeout is not already in effect. - if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { - checkLoadedTimeoutId = setTimeout(function () { - checkLoadedTimeoutId = 0; - checkLoaded(); - }, 50); - } - } - - inCheckLoaded = false; + } else if (cfg.packages) { + config.packages = cfg.packages; } - Module = function (map) { - this.events = getOwn(undefEvents, map.id) || {}; - this.map = map; - this.shim = getOwn(config.shim, map.id); - this.depExports = []; - this.depMaps = []; - this.depMatched = []; - this.pluginMaps = {}; - this.depCount = 0; - - /* this.exports this.factory - this.depMaps = [], - this.enabled, this.fetched - */ - }; - - Module.prototype = { - init: function (depMaps, factory, errback, options) { - options = options || {}; - - //Do not do more inits if already done. Can happen if there - //are multiple define calls for the same module. That is not - //a normal, common case, but it is also not unexpected. - if (this.inited) { - return; - } - - this.factory = factory; - - if (errback) { - //Register for errors on this module. - this.on('error', errback); - } else if (this.events.error) { - //If no errback already, but there are error listeners - //on this module, set up an errback to pass to the deps. - errback = bind(this, function (err) { - this.emit('error', err); - }); - } - - //Do a copy of the dependency array, so that - //source inputs are not modified. For example - //"shim" deps are passed in here directly, and - //doing a direct modification of the depMaps array - //would affect that config. - this.depMaps = depMaps && depMaps.slice(0); - - this.errback = errback; - - //Indicate this module has be initialized - this.inited = true; - - this.ignore = options.ignore; - - //Could have option to init this module in enabled mode, - //or could have been previously marked as enabled. However, - //the dependencies are not known until init is called. So - //if enabled previously, now trigger dependencies as enabled. - if (options.enabled || this.enabled) { - //Enable this module and dependencies. - //Will call this.check() - this.enable(); - } else { - this.check(); - } - }, - - defineDep: function (i, depExports) { - //Because of cycles, defined callback for a given - //export can be called more than once. - if (!this.depMatched[i]) { - this.depMatched[i] = true; - this.depCount -= 1; - this.depExports[i] = depExports; - } - }, - - fetch: function () { - if (this.fetched) { - return; - } - this.fetched = true; - - context.startTime = (new Date()).getTime(); - - var map = this.map; - - //If the manager is for a plugin managed resource, - //ask the plugin to load it now. - if (this.shim) { - context.makeRequire(this.map, { - enableBuildCallback: true - })(this.shim.deps || [], bind(this, function () { - return map.prefix ? this.callPlugin() : this.load(); - })); - } else { - //Regular dependency. - return map.prefix ? this.callPlugin() : this.load(); - } - }, - - load: function () { - var url = this.map.url; - - //Regular dependency. - if (!urlFetched[url]) { - urlFetched[url] = true; - context.load(this.map.id, url); - } - }, - - /** - * Checks if the module is ready to define itself, and if so, - * define it. - */ - check: function () { - if (!this.enabled || this.enabling) { - return; - } - - var err, cjsModule, - id = this.map.id, - depExports = this.depExports, - exports = this.exports, - factory = this.factory; - - if (!this.inited) { - this.fetch(); - } else if (this.error) { - this.emit('error', this.error); - } else if (!this.defining) { - //The factory could trigger another require call - //that would result in checking this module to - //define itself again. If already in the process - //of doing that, skip this work. - this.defining = true; - - if (this.depCount < 1 && !this.defined) { - if (isFunction(factory)) { - //If there is an error listener, favor passing - //to that instead of throwing an error. However, - //only do it for define()'d modules. require - //errbacks should not be called for failures in - //their callbacks (#699). However if a global - //onError is set, use that. - if ((this.events.error && this.map.isDefine) || - req.onError !== defaultOnError) { - try { - exports = context.execCb(id, factory, depExports, exports); - } catch (e) { - err = e; - } - } else { - exports = context.execCb(id, factory, depExports, exports); - } - - // Favor return value over exports. If node/cjs in play, - // then will not have a return value anyway. Favor - // module.exports assignment over exports object. - if (this.map.isDefine && exports === undefined) { - cjsModule = this.module; - if (cjsModule) { - exports = cjsModule.exports; - } else if (this.usingExports) { - //exports already set the defined value. - exports = this.exports; - } - } - - if (err) { - err.requireMap = this.map; - err.requireModules = this.map.isDefine ? [this.map.id] : null; - err.requireType = this.map.isDefine ? 'define' : 'require'; - return onError((this.error = err)); - } - - } else { - //Just a literal value - exports = factory; - } - - this.exports = exports; - - if (this.map.isDefine && !this.ignore) { - defined[id] = exports; - - if (req.onResourceLoad) { - req.onResourceLoad(context, this.map, this.depMaps); - } - } - - //Clean up - cleanRegistry(id); - - this.defined = true; - } - - //Finished the define stage. Allow calling check again - //to allow define notifications below in the case of a - //cycle. - this.defining = false; - - if (this.defined && !this.defineEmitted) { - this.defineEmitted = true; - this.emit('defined', this.exports); - this.defineEmitComplete = true; - } - - } - }, - - callPlugin: function () { - var map = this.map, - id = map.id, - //Map already normalized the prefix. - pluginMap = makeModuleMap(map.prefix); - - //Mark this as a dependency for this plugin, so it - //can be traced for cycles. - this.depMaps.push(pluginMap); - - on(pluginMap, 'defined', bind(this, function (plugin) { - var load, normalizedMap, normalizedMod, - bundleId = getOwn(bundlesMap, this.map.id), - name = this.map.name, - parentName = this.map.parentMap ? this.map.parentMap.name : null, - localRequire = context.makeRequire(map.parentMap, { - enableBuildCallback: true - }); - - //If current map is not normalized, wait for that - //normalized name to load instead of continuing. - if (this.map.unnormalized) { - //Normalize the ID if the plugin allows it. - if (plugin.normalize) { - name = plugin.normalize(name, function (name) { - return normalize(name, parentName, true); - }) || ''; - } - - //prefix and name should already be normalized, no need - //for applying map config again either. - normalizedMap = makeModuleMap(map.prefix + '!' + name, - this.map.parentMap); - on(normalizedMap, - 'defined', bind(this, function (value) { - this.init([], function () { return value; }, null, { - enabled: true, - ignore: true - }); - })); - - normalizedMod = getOwn(registry, normalizedMap.id); - if (normalizedMod) { - //Mark this as a dependency for this plugin, so it - //can be traced for cycles. - this.depMaps.push(normalizedMap); - - if (this.events.error) { - normalizedMod.on('error', bind(this, function (err) { - this.emit('error', err); - })); - } - normalizedMod.enable(); - } - - return; - } - - //If a paths config, then just load that file instead to - //resolve the plugin, as it is built into that paths layer. - if (bundleId) { - this.map.url = context.nameToUrl(bundleId); - this.load(); - return; - } - - load = bind(this, function (value) { - this.init([], function () { return value; }, null, { - enabled: true - }); - }); - - load.error = bind(this, function (err) { - this.inited = true; - this.error = err; - err.requireModules = [id]; - - //Remove temp unnormalized modules for this module, - //since they will never be resolved otherwise now. - eachProp(registry, function (mod) { - if (mod.map.id.indexOf(id + '_unnormalized') === 0) { - cleanRegistry(mod.map.id); - } - }); - - onError(err); - }); - - //Allow plugins to load other code without having to know the - //context or how to 'complete' the load. - load.fromText = bind(this, function (text, textAlt) { - /*jslint evil: true */ - var moduleName = map.name, - moduleMap = makeModuleMap(moduleName), - hasInteractive = useInteractive; - - //As of 2.1.0, support just passing the text, to reinforce - //fromText only being called once per resource. Still - //support old style of passing moduleName but discard - //that moduleName in favor of the internal ref. - if (textAlt) { - text = textAlt; - } - - //Turn off interactive script matching for IE for any define - //calls in the text, then turn it back on at the end. - if (hasInteractive) { - useInteractive = false; - } - - //Prime the system by creating a module instance for - //it. - getModule(moduleMap); - - //Transfer any config to this other module. - if (hasProp(config.config, id)) { - config.config[moduleName] = config.config[id]; - } - - try { - req.exec(text); - } catch (e) { - return onError(makeError('fromtexteval', - 'fromText eval for ' + id + - ' failed: ' + e, - e, - [id])); - } - - if (hasInteractive) { - useInteractive = true; - } - - //Mark this as a dependency for the plugin - //resource - this.depMaps.push(moduleMap); - - //Support anonymous modules. - context.completeLoad(moduleName); - - //Bind the value of that module to the value for this - //resource ID. - localRequire([moduleName], load); - }); - - //Use parentName here since the plugin's name is not reliable, - //could be some weird string with no path that actually wants to - //reference the parentName's path. - plugin.load(map.name, localRequire, load, config); - })); - - context.enable(pluginMap, this); - this.pluginMaps[pluginMap.id] = pluginMap; - }, - - enable: function () { - enabledRegistry[this.map.id] = this; - this.enabled = true; - - //Set flag mentioning that the module is enabling, - //so that immediate calls to the defined callbacks - //for dependencies do not trigger inadvertent load - //with the depCount still being zero. - this.enabling = true; - - //Enable each dependency - each(this.depMaps, bind(this, function (depMap, i) { - var id, mod, handler; - - if (typeof depMap === 'string') { - //Dependency needs to be converted to a depMap - //and wired up to this module. - depMap = makeModuleMap(depMap, - (this.map.isDefine ? this.map : this.map.parentMap), - false, - !this.skipMap); - this.depMaps[i] = depMap; - - handler = getOwn(handlers, depMap.id); - - if (handler) { - this.depExports[i] = handler(this); - return; - } - - this.depCount += 1; - - on(depMap, 'defined', bind(this, function (depExports) { - this.defineDep(i, depExports); - this.check(); - })); - - if (this.errback) { - on(depMap, 'error', bind(this, this.errback)); - } - } - - id = depMap.id; - mod = registry[id]; - - //Skip special modules like 'require', 'exports', 'module' - //Also, don't call enable if it is already enabled, - //important in circular dependency cases. - if (!hasProp(handlers, id) && mod && !mod.enabled) { - context.enable(depMap, this); - } - })); - - //Enable each plugin that is used in - //a dependency - eachProp(this.pluginMaps, bind(this, function (pluginMap) { - var mod = getOwn(registry, pluginMap.id); - if (mod && !mod.enabled) { - context.enable(pluginMap, this); - } - })); - - this.enabling = false; - - this.check(); - }, - - on: function (name, cb) { - var cbs = this.events[name]; - if (!cbs) { - cbs = this.events[name] = []; - } - cbs.push(cb); - }, - - emit: function (name, evt) { - each(this.events[name], function (cb) { - cb(evt); - }); - if (name === 'error') { - //Now that the error handler was triggered, remove - //the listeners, since this broken Module instance - //can stay around for a while in the registry. - delete this.events[name]; - } - } - }; + cfg.paths && + Object.keys(cfg.paths).forEach(function(p) { + config.paths[p] = cfg.paths[p]; + }); - function callGetModule(args) { - //Skip modules already defined. - if (!hasProp(defined, args[0])) { - getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); - } + if ( + cfg.useCache && + global.caches && + (location.protocol === "https:" || location.hostname == "localhost") + ) { + config.useCache = true; + checkCache(); } - function removeListener(node, func, name, ieName) { - //Favor detachEvent because of IE9 - //issue, see attachEvent/addEventListener comment elsewhere - //in this file. - if (node.detachEvent && !isOpera) { - //Probably IE. If not it will throw an error, which will be - //useful to know. - if (ieName) { - node.detachEvent(ieName, func); - } - } else { - node.removeEventListener(name, func, false); + if (cfg.transform) config.transform = cfg.transform; + if (/\bes5\b/.test(cfg.transform) && !global.shimIncluded) { + if (!console.assert) { + console.assert = function assert() {}; // This method is used by the following es6 shim. } + var oldFlags = RegExp.prototype.flags; + RegExp.prototype.flags = true; + require(["js-polyfills/es6"]); + RegExp.prototype.flags = oldFlags; + global.shimIncluded = true; } - /** - * Given an event from a script node, get the requirejs info from it, - * and then removes the event listeners on the node. - * @param {Event} evt - * @returns {Object} - */ - function getScriptData(evt) { - //Using currentTarget instead of target for Firefox 2.0's sake. Not - //all old browsers will be supported, but this one was easy enough - //to support and still makes sense. - var node = evt.currentTarget || evt.srcElement; + if (cfg.assetUrl) config.assetUrl = cfg.assetUrl; - //Remove the listeners once here. - removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); - removeListener(node, context.onScriptError, 'error'); + if (cfg.$keepLoaders != undefined) config.$keepLoaders = cfg.$keepLoaders; + }); - return { - node: node, - id: node && node.getAttribute('data-requiremodule') - }; - } + require.resetConfig = function(cfg) { + var location = global.location; + var baseUrl = location ? location.protocol + "//" + location.host + + location.pathname.split("/").slice(0, -1).join("/") : ""; + config.packages = Object.create(null); + config.paths = Object.create(null); + config.baseUrl = baseUrl; + config.useCache = false; + config.transform = ""; + if (cfg) require.config(cfg); + }; - function intakeDefines() { - var args; + require.getConfig = function() { + var script = document.querySelector("script[src*=require]"); + return { + packages: config.packages, + paths: config.paths, + baseUrl: config.baseUrl, + useCache: config.useCache, + transform: config.transform, + host: host, + requireSourceUrl: !config.packed && script && script.src, + assetUrl: config.assetUrl, + }; + }; - //Any defined modules in the global queue, intake them now. - takeGlobalQueue(); + require.resetConfig(); - //Make sure any remaining defQueue items get properly processed. - while (defQueue.length) { - args = defQueue.shift(); - if (args[0] === null) { - return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); - } else { - //args are id, deps, factory. Should be normalized by the - //define() function. - callGetModule(args); - } - } + define.undef = require.undef = function(module, recursive) { + module = normalizeName("", module); + if (recursive) { + var root = (module + "/").replace(/\/+$/, "/"); + undefAll(root, define.errors); + undefAll(root, define.loaded); + undefAll(root, define.modules); + undefAll(root, define.loading); + } else { + undefOne(module, require.toUrl(module, ".js")); } + }; - context = { - config: config, - contextName: contextName, - registry: registry, - defined: defined, - urlFetched: urlFetched, - defQueue: defQueue, - Module: Module, - makeModuleMap: makeModuleMap, - nextTick: req.nextTick, - onError: onError, - - /** - * Set a configuration for the context. - * @param {Object} cfg config object to integrate. - */ - configure: function (cfg) { - //Make sure the baseUrl ends in a slash. - if (cfg.baseUrl) { - if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { - cfg.baseUrl += '/'; - } - } - - //Save off the paths since they require special processing, - //they are additive. - var shim = config.shim, - objs = { - paths: true, - bundles: true, - config: true, - map: true - }; - - eachProp(cfg, function (value, prop) { - if (objs[prop]) { - if (!config[prop]) { - config[prop] = {}; - } - mixin(config[prop], value, true, true); - } else { - config[prop] = value; - } - }); - - //Reverse map the bundles - if (cfg.bundles) { - eachProp(cfg.bundles, function (value, prop) { - each(value, function (v) { - if (v !== prop) { - bundlesMap[v] = prop; - } - }); - }); - } - - //Merge shim - if (cfg.shim) { - eachProp(cfg.shim, function (value, id) { - //Normalize the structure - if (isArray(value)) { - value = { - deps: value - }; - } - if ((value.exports || value.init) && !value.exportsFn) { - value.exportsFn = context.makeShimExports(value); - } - shim[id] = value; - }); - config.shim = shim; - } - - //Adjust packages if necessary. - if (cfg.packages) { - each(cfg.packages, function (pkgObj) { - var location, name; - - pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; - - name = pkgObj.name; - location = pkgObj.location; - if (location) { - config.paths[name] = pkgObj.location; - } - - //Save pointer to main module ID for pkg name. - //Remove leading dot in main, so main paths are normalized, - //and remove any trailing .js, since different package - //envs have different conventions: some use a module name, - //some use a file name. - config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main') - .replace(currDirRegExp, '') - .replace(jsSuffixRegExp, ''); - }); - } - - //If there are any "waiting to execute" modules in the registry, - //update the maps for them, since their info, like URLs to load, - //may have changed. - eachProp(registry, function (mod, id) { - //If module already has init called, since it is too - //late to modify them, and ignore unnormalized ones - //since they are transient. - if (!mod.inited && !mod.map.unnormalized) { - mod.map = makeModuleMap(id); - } - }); - - //If a deps array or a config callback is specified, then call - //require with those args. This is useful when require is defined as a - //config object before require.js is loaded. - if (cfg.deps || cfg.callback) { - context.require(cfg.deps || [], cfg.callback); - } - }, - - makeShimExports: function (value) { - function fn() { - var ret; - if (value.init) { - ret = value.init.apply(global, arguments); - } - return ret || (value.exports && getGlobal(value.exports)); - } - return fn; - }, - - makeRequire: function (relMap, options) { - options = options || {}; - - function localRequire(deps, callback, errback) { - var id, map, requireMod; - - if (options.enableBuildCallback && callback && isFunction(callback)) { - callback.__requireJsBuild = true; - } - - if (typeof deps === 'string') { - if (isFunction(callback)) { - //Invalid call - return onError(makeError('requireargs', 'Invalid require call'), errback); - } - - //If require|exports|module are requested, get the - //value for them from the special handlers. Caveat: - //this only works while module is being defined. - if (relMap && hasProp(handlers, deps)) { - return handlers[deps](registry[relMap.id]); - } - - //Synchronous access to one module. If require.get is - //available (as in the Node adapter), prefer that. - if (req.get) { - return req.get(context, deps, relMap, localRequire); - } - - //Normalize module name, if it contains . or .. - map = makeModuleMap(deps, relMap, false, true); - id = map.id; - - if (!hasProp(defined, id)) { - return onError(makeError('notloaded', 'Module name "' + - id + - '" has not been loaded yet for context: ' + - contextName + - (relMap ? '' : '. Use require([])'))); - } - return defined[id]; - } - - //Grab defines waiting in the global queue. - intakeDefines(); - - //Mark all the dependencies as needing to be loaded. - context.nextTick(function () { - //Some defines could have been added since the - //require call, collect them. - intakeDefines(); - - requireMod = getModule(makeModuleMap(null, relMap)); - - //Store if map config should be applied to this require - //call for dependencies. - requireMod.skipMap = options.skipMap; - - requireMod.init(deps, callback, errback, { - enabled: true - }); - - checkLoaded(); - }); - - return localRequire; - } - - mixin(localRequire, { - isBrowser: isBrowser, - - /** - * Converts a module name + .extension into an URL path. - * *Requires* the use of a module name. It does not support using - * plain URLs like nameToUrl. - */ - toUrl: function (moduleNamePlusExt) { - var ext, - index = moduleNamePlusExt.lastIndexOf('.'), - segment = moduleNamePlusExt.split('/')[0], - isRelative = segment === '.' || segment === '..'; - - //Have a file extension alias, and it is not the - //dots from a relative path. - if (index !== -1 && (!isRelative || index > 1)) { - ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); - moduleNamePlusExt = moduleNamePlusExt.substring(0, index); - } - - return context.nameToUrl(normalize(moduleNamePlusExt, - relMap && relMap.id, true), ext, true); - }, - - defined: function (id) { - return hasProp(defined, makeModuleMap(id, relMap, false, true).id); - }, - - specified: function (id) { - id = makeModuleMap(id, relMap, false, true).id; - return hasProp(defined, id) || hasProp(registry, id); - } - }); - - //Only allow undef on top level require calls - if (!relMap) { - localRequire.undef = function (id) { - //Bind any waiting define() calls to this context, - //fix for #408 - takeGlobalQueue(); - - var map = makeModuleMap(id, relMap, true), - mod = getOwn(registry, id); - - removeScript(id); - - delete defined[id]; - delete urlFetched[map.url]; - delete undefEvents[id]; - - //Clean queued defines too. Go backwards - //in array so that the splices do not - //mess up the iteration. - eachReverse(defQueue, function(args, i) { - if(args[0] === id) { - defQueue.splice(i, 1); - } - }); - - if (mod) { - //Hold on to listeners in case the - //module will be attempted to be reloaded - //using a different config. - if (mod.events.defined) { - undefEvents[id] = mod.events; - } - - cleanRegistry(id); - } - }; - } - - return localRequire; - }, - - /** - * Called to enable a module if it is still in the registry - * awaiting enablement. A second arg, parent, the parent module, - * is passed in for context, when this method is overridden by - * the optimizer. Not shown here to keep code compact. - */ - enable: function (depMap) { - var mod = getOwn(registry, depMap.id); - if (mod) { - getModule(depMap).enable(); - } - }, - - /** - * Internal method used by environment adapters to complete a load event. - * A load event could be a script load or just a load pass from a synchronous - * load call. - * @param {String} moduleName the name of the module to potentially complete. - */ - completeLoad: function (moduleName) { - var found, args, mod, - shim = getOwn(config.shim, moduleName) || {}, - shExports = shim.exports; - - takeGlobalQueue(); - - while (defQueue.length) { - args = defQueue.shift(); - if (args[0] === null) { - args[0] = moduleName; - //If already found an anonymous module and bound it - //to this name, then this is some other anon module - //waiting for its completeLoad to fire. - if (found) { - break; - } - found = true; - } else if (args[0] === moduleName) { - //Found matching define call for this script! - found = true; - } - - callGetModule(args); - } - - //Do this after the cycle of callGetModule in case the result - //of those calls/init calls changes the registry. - mod = getOwn(registry, moduleName); - - if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { - if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { - if (hasPathFallback(moduleName)) { - return; - } else { - return onError(makeError('nodefine', - 'No define call for ' + moduleName, - null, - [moduleName])); - } - } else { - //A script that does not call define(), so just simulate - //the call for it. - callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); - } - } - - checkLoaded(); - }, - - /** - * Converts a module name to a file path. Supports cases where - * moduleName may actually be just an URL. - * Note that it **does not** call normalize on the moduleName, - * it is assumed to have already been normalized. This is an - * internal API, not a public one. Use toUrl for the public API. - */ - nameToUrl: function (moduleName, ext, skipExt) { - var paths, syms, i, parentModule, url, - parentPath, bundleId, - pkgMain = getOwn(config.pkgs, moduleName); - - if (pkgMain) { - moduleName = pkgMain; - } - - bundleId = getOwn(bundlesMap, moduleName); - - if (bundleId) { - return context.nameToUrl(bundleId, ext, skipExt); - } - - //If a colon is in the URL, it indicates a protocol is used and it is just - //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) - //or ends with .js, then assume the user meant to use an url and not a module id. - //The slash is important for protocol-less URLs as well as full paths. - if (req.jsExtRegExp.test(moduleName)) { - //Just a plain path, not module name lookup, so just return it. - //Add extension if it is included. This is a bit wonky, only non-.js things pass - //an extension, this method probably needs to be reworked. - url = moduleName + (ext || ''); - } else { - //A module that needs to be converted to a path. - paths = config.paths; - - syms = moduleName.split('/'); - //For each module name segment, see if there is a path - //registered for it. Start with most specific name - //and work up from it. - for (i = syms.length; i > 0; i -= 1) { - parentModule = syms.slice(0, i).join('/'); - - parentPath = getOwn(paths, parentModule); - if (parentPath) { - //If an array, it means there are a few choices, - //Choose the one that is desired - if (isArray(parentPath)) { - parentPath = parentPath[0]; - } - syms.splice(0, i, parentPath); - break; - } - } - - //Join the path parts together, then figure out if baseUrl is needed. - url = syms.join('/'); - url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); - url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; - } - - return config.urlArgs ? url + - ((url.indexOf('?') === -1 ? '?' : '&') + - config.urlArgs) : url; - }, - - //Delegates to req.load. Broken out as a separate function to - //allow overriding in the optimizer. - load: function (id, url) { - req.load(context, id, url); - }, - - /** - * Executes a module callback function. Broken out as a separate function - * solely to allow the build system to sequence the files in the built - * layer in the right sequence. - * - * @private - */ - execCb: function (name, callback, args, exports) { - return callback.apply(exports, args); - }, - - /** - * callback for script loads, used to check status of loading. - * - * @param {Event} evt the event from the browser for the script - * that was loaded. - */ - onScriptLoad: function (evt) { - //Using currentTarget instead of target for Firefox 2.0's sake. Not - //all old browsers will be supported, but this one was easy enough - //to support and still makes sense. - if (evt.type === 'load' || - (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { - //Reset interactive script so a script node is not held onto for - //to long. - interactiveScript = null; - - //Pull out the name of the module and the context. - var data = getScriptData(evt); - context.completeLoad(data.id); - } - }, + function undefOne(module, path) { + delete define.errors[module]; + delete define.loaded[module]; + delete define.modules[module]; + delete define.loading[module]; + delete define.fetchedUrls[path]; + } - /** - * Callback for script errors. - */ - onScriptError: function (evt) { - var data = getScriptData(evt); - if (!hasPathFallback(data.id)) { - return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); + function undefAll(module, hash) { + Object.keys(hash).forEach(function(key) { + var i = key.indexOf("!") + 1; + if (key.lastIndexOf(module, 0) == 0) undefOne(key, require.toUrl(key, ".js")); + if (i) { + var plugin = key.slice(0, i - 1); + var resource = key.slice(i); + if (resource.lastIndexOf(module, 0) == 0 || plugin.lastIndexOf(module, 0) == 0) { + undefOne(key, require.toUrl(key, "")); + undefOne(resource, require.toUrl(resource, "")); } } - }; - - context.require = context.makeRequire(); - return context; + }); } - /** - * Main entry point. - * - * If the only argument to require is a string, then the module that - * is represented by that string is fetched for the appropriate context. - * - * If the first argument is an array, then it will be treated as an array - * of dependency string names to fetch. An optional function callback can - * be specified to execute when all of those dependencies are available. - * - * Make a local req variable to help Caja compliance (it assumes things - * on a require that are not standardized), and to give a short - * name for minification/local scope use. - */ - req = requirejs = function (deps, callback, errback, optional) { + require.toUrl = function(moduleName, ext, skipExt, isStatic) { + var absRe = /^([\w\+\.\-]+:|\/)/; + var index = moduleName.indexOf("!"); + if (index !== -1 || !ext || /^\//.test(moduleName)) ext = ""; - //Find the right context, use default - var context, config, - contextName = defContextName; + var paths = config.paths; + var pkgs = config.packages; - // Determine if have config object in the call. - if (!isArray(deps) && typeof deps !== 'string') { - // deps is a config object - config = deps; - if (isArray(callback)) { - // Adjust args if there are dependencies - deps = callback; - callback = errback; - errback = optional; - } else { - deps = []; + var testPath = moduleName; + var tail = ""; + while (testPath) { + if (paths[testPath]) { + moduleName = paths[testPath] + tail; + break; } + if (pkgs[testPath]) { + moduleName = pkgs[testPath].location + (tail || pkgs[testPath].main); + break; + } + var i = testPath.lastIndexOf("/"); + if (i === -1) break; + tail = testPath.substr(i) + tail; + testPath = testPath.slice(0, i); } - if (config && config.context) { - contextName = config.context; - } + if (skipExt) return testPath; - context = getOwn(contexts, contextName); - if (!context) { - context = contexts[contextName] = req.s.newContext(contextName); + var url = ext == ".js" && moduleName.slice(-3) == ext ? moduleName : moduleName + ext; + if (moduleName.slice(-3) == ".ts") { + url = moduleName.slice(0, -3) + ext; } - - if (config) { - context.configure(config); + if (!absRe.test(url)) { + if (ext == ".js" && require.config.transform) url = addTransform(url, moduleName); + var baseUrl = config.baseUrl; + if (baseUrl.slice(-1) != "/") baseUrl += "/"; + url = baseUrl + url; } - - return context.require(deps, callback, errback); - }; - - /** - * Support require.config() to make it easier to cooperate with other - * AMD loaders on globally agreed names. - */ - req.config = function (config) { - return req(config); + if (url[0] == "/") url = host + url; + return url; }; - /** - * Execute something after the current tick - * of the event loop. Override for other envs - * that have a better solution than setTimeout. - * @param {Function} fn function to execute later. - */ - req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { - setTimeout(fn, 4); - } : function (fn) { fn(); }; - - /** - * Export require as a global, but only if it does not already exist. - */ - if (!require) { - require = req; + function addTransform(url, moduleName) { + var transform = require.config.transform; + if (!Array.isArray(transform)) transform = [transform]; + return ( + "~/" + + transform + .map(function(part) { + if (typeof part == "string") return part; + if (moduleName.lastIndexOf(part[0], 0) != -1) return part[1]; + }) + .filter(Boolean) + .join(",") + + "/" + + url + ).replace("//", "/"); } - req.version = version; - - //Used to filter out dependencies that are already paths. - req.jsExtRegExp = /^\/|:|\?|\.js$/; - req.isBrowser = isBrowser; - s = req.s = { - contexts: contexts, - newContext: newContext - }; - - //Create default context. - req({}); - - //Exports some context-sensitive methods on global require. - each([ - 'toUrl', - 'undef', - 'defined', - 'specified' - ], function (prop) { - //Reference from contexts instead of early binding to default context, - //so that during builds, the latest instance of the default context - //with its config gets used. - req[prop] = function () { - var ctx = contexts[defContextName]; - return ctx.require[prop].apply(ctx, arguments); + function loadText(path, callback) { + var xhr = new global.XMLHttpRequest(); + xhr.open("GET", path, true); + xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); + xhr.onload = function(e) { + if (xhr.status > 399 && xhr.status < 600) return callback(xhr); + callback(null, xhr.responseText, xhr); }; - }); - - if (isBrowser) { - head = s.head = document.getElementsByTagName('head')[0]; - //If BASE tag is in play, using appendChild is a problem for IE6. - //When that browser dies, this can be removed. Details in this jQuery bug: - //http://dev.jquery.com/ticket/2709 - baseElement = document.getElementsByTagName('base')[0]; - if (baseElement) { - head = s.head = baseElement.parentNode; - } + xhr.onabort = xhr.onerror = function(e) { + callback(e); + }; + xhr.send(""); } - /** - * Any errors that require explicitly generates will be passed to this - * function. Intercept/override it if you want custom error handling. - * @param {Error} err the error object. - */ - req.onError = defaultOnError; - - /** - * Creates the node for the load command. Only used in browser envs. - */ - req.createNode = function (config, moduleName, url) { - var node = config.xhtml ? - document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : - document.createElement('script'); - node.type = config.scriptType || 'text/javascript'; - node.charset = 'utf-8'; - node.async = true; - return node; + /*** cache ***/ + var host = + location.protocol + "//" + location.hostname + (location.port ? ":" + location.port : ""); + var loadScript = function(path, id, callback) { + if (!/^\w+:/.test(path)) path = host + path; + var onLoad = function(e, val) { + if (e) return processLoadQueue({id: id, path: path}); + if (!/^(\s|\/\*([^*]|[*](?!\/))*\*\/|\/\/.*[\r]?\n)*define\s*\(\s*function\s*\(\s*require\b/.test(val) && !/define\(\[\],/.test(val)) + val = "define(function(require, exports, module){" + val + "\n});" + nextModule = {name: id}; + /* eslint no-eval:0 */ + global.eval(val + "\n//# sourceURL=" + path); + callback(null, id); + return define.loaded[id]; + }; + loadCached(path, onLoad); }; - /** - * Does the request to load a module for the browser case. - * Make this a separate function to allow other environments - * to override it. - * - * @param {Object} context the require context to find state. - * @param {String} moduleName the name of the module. - * @param {Object} url the URL to the module. - */ - req.load = function (context, moduleName, url) { - var config = (context && context.config) || {}, - node; - if (isBrowser) { - //In the browser so use a script tag - node = req.createNode(config, moduleName, url); - - node.setAttribute('data-requirecontext', context.contextName); - node.setAttribute('data-requiremodule', moduleName); - - //Set up load listener. Test attachEvent first because IE9 has - //a subtle issue in its addEventListener and script onload firings - //that do not match the behavior of all other browsers with - //addEventListener support, which fire the onload event for a - //script right after the script execution. See: - //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution - //UNFORTUNATELY Opera implements attachEvent but does not follow the script - //script execution mode. - if (node.attachEvent && - //Check if node.attachEvent is artificially added by custom script or - //natively supported by browser - //read https://github.com/jrburke/requirejs/issues/187 - //if we can NOT find [native code] then it must NOT natively supported. - //in IE8, node.attachEvent does not have toString() - //Note the test for "[native code" with no closing brace, see: - //https://github.com/jrburke/requirejs/issues/273 - !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && - !isOpera) { - //Probably IE. IE (at least 6-8) do not fire - //script onload right after executing the script, so - //we cannot tie the anonymous define call to a name. - //However, IE reports the script as being in 'interactive' - //readyState at the time of the define call. - useInteractive = true; - - node.attachEvent('onreadystatechange', context.onScriptLoad); - //It would be great to add an error handler here to catch - //404s in IE9+. However, onreadystatechange will fire before - //the error handler, so that does not help. If addEventListener - //is used, then IE will fire error before load, but we cannot - //use that pathway given the connect.microsoft.com issue - //mentioned above about not doing the 'script execute, - //then fire the script load event listener before execute - //next script' that other browsers do. - //Best hope: IE10 fixes the issues, - //and then destroys all installs of IE 6-9. - //node.attachEvent('onerror', context.onScriptError); - } else { - node.addEventListener('load', context.onScriptLoad, false); - node.addEventListener('error', context.onScriptError, false); - } - node.src = url; + var loadCached = function(path, callback) { + return loadText(path, callback); + }; - //For some cache cases in IE 6-8, the script executes before the end - //of the appendChild execution, so to tie an anonymous define - //call to the module name (which is stored on the node), hold on - //to a reference to this node, but clear after the DOM insertion. - currentlyAddingScript = node; - if (baseElement) { - head.insertBefore(node, baseElement); + require.load = function(module) { + var i = module.indexOf("!") + 1; + if (i) { + var plugin = module.substring(0, i); + module = module.substr(i); + if (typeof require[plugin] == "function") { + require[plugin](module, processLoadQueue); + } else if (config.baseUrl) { + if (require[plugin]) return (require[plugin][plugin + module] = 1); + require[plugin] = Object.create(null); + require[plugin][plugin + module] = 1; + require([plugin.slice(0, -1)], function(p) { + var pending = require[plugin]; + definePlugin(plugin, p); + Object.keys(pending).forEach(function(p) { + delete define.loading[p]; + }); + require(Object.keys(pending)); + }); } else { - head.appendChild(node); - } - currentlyAddingScript = null; - - return node; - } else if (isWebWorker) { - try { - //In a web worker, use importScripts. This is not a very - //efficient use of importScripts, importScripts will block until - //its script is downloaded and evaluated. However, if web workers - //are in play, the expectation that a build has been done so that - //only one script needs to be loaded anyway. This may need to be - //reevaluated if other use cases become common. - importScripts(url); - - //Account for anonymous modules - context.completeLoad(moduleName); - } catch (e) { - context.onError(makeError('importscripts', - 'importScripts failed for ' + - moduleName + ' at ' + url, - e, - [moduleName])); + console.error("require plugin " + plugin + "missing"); } + } else { + var url = require.toUrl(module, ".js"); + if (define.fetchedUrls[url] & 1) return false; + define.fetchedUrls[url] |= 1; + loadScript(url, module, processLoadQueue); } }; - function getInteractiveScript() { - if (interactiveScript && interactiveScript.readyState === 'interactive') { - return interactiveScript; - } - - eachReverse(scripts(), function (script) { - if (script.readyState === 'interactive') { - return (interactiveScript = script); - } - }); - return interactiveScript; + function definePlugin(plugin, p) { + require[plugin] = function(moduleName, processLoadQueue) { + p.load(moduleName, require, function(value) { + define(plugin + moduleName, [], function() { + return value; + }); + processLoadQueue(); + }); + }; } - //Look for a data-main script attribute, which could also adjust the baseUrl. - if (isBrowser && !cfg.skipDataMain) { - //Figure out baseUrl. Get it from the script tag with require.js in it. - eachReverse(scripts(), function (script) { - //Set the 'head' where we can append children by - //using the script's parent. - if (!head) { - head = script.parentNode; - } - - //Look for a data-main attribute to set main script for the page - //to load. If it is there, the path to data main becomes the - //baseUrl, if it is not already set. - dataMain = script.getAttribute('data-main'); - if (dataMain) { - //Preserve dataMain in case it is a path (i.e. contains '?') - mainScript = dataMain; - - //Set final baseUrl if there is not already an explicit one. - if (!cfg.baseUrl) { - //Pull off the directory of data-main for use as the - //baseUrl. - src = mainScript.split('/'); - mainScript = src.pop(); - subPath = src.length ? src.join('/') + '/' : './'; - - cfg.baseUrl = subPath; - } - - //Strip off any trailing .js since mainScript is now - //like a module name. - mainScript = mainScript.replace(jsSuffixRegExp, ''); - - //If mainScript is still a path, fall back to dataMain - if (req.jsExtRegExp.test(mainScript)) { - mainScript = dataMain; - } - - //Put the data-main script in the files to load. - cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; - - return true; - } + /*** plugins ***/ + var syncLoaders = /^(language!|webworker!|vfs!|asset-url!)/; + require["language!"] = function(module, callback) { + define("language!" + module, [], module); + callback(); + }; + require["webworker!"] = function(module, callback) { + var url = require.toUrl(module.split("!").pop(), ".js"); + define("webworker!" + module, [], url); + callback(); + }; + require["asset-url!"] = function(module, callback) { + var url = require.toUrl(module.split("!").pop(), "", "", true); + define("asset-url!" + module, [], url); + callback(); + }; + require["vfs!"] = function(module, callback) { + var url = require.MODULE_LOAD_URL + "/~node/" + module; + if (define.fetchedUrls[url] & 4) return false; + define.fetchedUrls[url] |= 4; + define("vfs!" + module, [], { + srcUrl: url, + path: module, }); - } - - /** - * The function that handles definitions of modules. Differs from - * require() in that a string for the module should be the first argument, - * and the function to execute after dependencies are loaded should - * return a value to define the module corresponding to the first argument's - * name. - */ - define = function (name, deps, callback) { - var node, context; - - //Allow for anonymous modules - if (typeof name !== 'string') { - //Adjust args appropriately - callback = deps; - deps = name; - name = null; - } - - //This module may not have dependencies - if (!isArray(deps)) { - callback = deps; - deps = null; - } - - //If no name, and callback is a function, then figure out if it a - //CommonJS thing with dependencies. - if (!deps && isFunction(callback)) { - deps = []; - //Remove comments from the callback string, - //look for require calls, and pull them into the dependencies, - //but only if there are function args. - if (callback.length) { - callback - .toString() - .replace(commentRegExp, '') - .replace(cjsRequireRegExp, function (match, dep) { - deps.push(dep); - }); - - //May be a CommonJS thing even without require calls, but still - //could use exports, and module. Avoid doing exports and module - //work though if it just needs require. - //REQUIRES the function to expect the CommonJS variables in the - //order listed below. - deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); - } - } - - //If in IE 6-8 and hit an anonymous define() call, do the interactive - //work. - if (useInteractive) { - node = currentlyAddingScript || getInteractiveScript(); - if (node) { - if (!name) { - name = node.getAttribute('data-requiremodule'); - } - context = contexts[node.getAttribute('data-requirecontext')]; - } - } - - //Always save off evaluating the def call until the script onload handler. - //This allows multiple modules to be in a file without prematurely - //tracing dependencies, and allows for anonymous module support, - //where the module name is not known until the script onload event - //occurs. If no context, use the global queue, and get it processed - //in the onscript load callback. - (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); + callback(); }; - - define.amd = { - jQuery: true + require["text!"] = function(module, callback) { + var url = require.toUrl(module); + if (define.fetchedUrls[url] & 2) return false; + define.fetchedUrls[url] |= 2; + var onLoad = function(e, val) { + if (e) console.error("Couldn't load module " + module, e); + define("text!" + module, [], val); + callback(); + }; + loadCached(url, onLoad); + }; + require["json!"] = function(module, callback) { + require["text!"](module, function() { + var val = JSON.parse(require("text!" + module)); + define("json!" + module, [], val); + callback(); + }); + }; + require["ace/requirejs/text!"] = function(module, callback) { + var url = require.toUrl(module); + if (define.fetchedUrls[url] & 2) return false; + define.fetchedUrls[url] |= 2; + var onLoad = function(e, val) { + if (e) console.error("Couldn't load module " + module, e); + define("ace/requirejs/text!" + module, [], val); + callback(); + }; + loadCached(url, onLoad); + }; + require["architect!"] = function(module, callback) { + var url = require.toUrl(module, ".js"); + if (define.fetchedUrls[url] & 1) return false; + define.fetchedUrls[url] |= 1; + loadScript(url, "architect!" + module, processLoadQueue); }; + function activateArchitectModule(_1, _2, _3) { + var module = this; + return function() { + module.pluginFactory(_1, _2, _3); + if (typeof module.exports == "function" && module.exports.consumes) { + return module.exports.apply(this, arguments); + } + return module.exports; + }; + } + + /*** add global define ***/ + if (!global.define || !global.define.packaged) { + define.original = global.define; + global.define = define; + global.define.packaged = true; + } + if (!global.require || !global.require.packaged) { + global.require = require; + global.require.packaged = true; + } - /** - * Executes the text. Normally just uses eval, but can be modified - * to use a better, environment-specific call. Only used for transpiling - * loader plugins, not for plain JS modules. - * @param {String} text the text to execute/evaluate. - */ - req.exec = function (text) { - /*jslint evil: true */ - return eval(text); - }; + if (!global.requirejs) global.requirejs = require; - //Set up with config info. - req(cfg); -}(this)); + global.miniRequire = require; +})(); diff --git a/demo/kitchen-sink/styles.css b/demo/kitchen-sink/styles.css index b9ace9c6390..d669a716c4a 100644 --- a/demo/kitchen-sink/styles.css +++ b/demo/kitchen-sink/styles.css @@ -48,10 +48,80 @@ body { border-left: 1px solid; } -/* .ace_text-input { +.toggleButton { + display: inline-block; + cursor: pointer; + position: absolute; +} +.toggleButton>div { + width: 15px; + height: 2px; + margin: 3px 2px; + background-color: #eee; + pointer-events: none; + transition: 0.5s; +} + +#sidePanel *:focus { + outline: 3px solid orange; +} + +#sidePanel a { + display: inline-block; +} + +#sidePanel:not(.closed) .toggleButton >div:nth-child(1) {transform: translate(0px, 5px) rotate(-45deg)} +#sidePanel:not(.closed) .toggleButton >div:nth-child(2) {opacity: 0} +#sidePanel:not(.closed) .toggleButton >div:nth-child(3) {transform: translate(0px, -5px) rotate(45deg)} +#sidePanel.closed>*:not(.toggleButton) {display: none} + +.show-text-input .ace_text-input { z-index: 10!important; opacity: 1!important; background: rgb(84, 0, 255)!important; color: rgb(255, 255, 255)!important; width: 10em!important; -}*/ +} +.text-input-debug { + height: 100px!important; + position: absolute!important; + transform: none!important; + top: 0px!important; + left: 7px!important; + width: 260px!important; + z-index: 1000!important; + opacity: 1!important; + font-size: 1em!important; +} + + +.language_highlight_error { + position: absolute; + border-bottom: dotted 1px #e00404; + z-index: 2000; + border-radius: 0; +} +.language_highlight_warning { + position: absolute; + border-bottom: solid 1px #DDC50F; + z-index: 2000; + border-radius: 0; +} +.language_highlight_info { + position: absolute; + border-bottom: dotted 1px #999; + z-index: 2000; + border-radius: 0; +} +.language_highlight_text, .language_highlight_read, .language_highlight_write { + position: absolute; + box-sizing: border-box; + border: solid 1px #888; + z-index: 2000; +} +.language_highlight_write { + border: solid 1px #F88; +} +.ace_tooltip pre { + margin: 0; +} \ No newline at end of file diff --git a/demo/kitchen-sink/token_tooltip.js b/demo/kitchen-sink/token_tooltip.js index 9e607f69f6b..f352463aecb 100644 --- a/demo/kitchen-sink/token_tooltip.js +++ b/demo/kitchen-sink/token_tooltip.js @@ -1,34 +1,3 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { "use strict"; var dom = require("ace/lib/dom"); @@ -37,27 +6,25 @@ var event = require("ace/lib/event"); var Range = require("ace/range").Range; var Tooltip = require("ace/tooltip").Tooltip; -function TokenTooltip (editor) { - if (editor.tokenTooltip) - return; - Tooltip.call(this, editor.container); - editor.tokenTooltip = this; - this.editor = editor; - - this.update = this.update.bind(this); - this.onMouseMove = this.onMouseMove.bind(this); - this.onMouseOut = this.onMouseOut.bind(this); - event.addListener(editor.renderer.scroller, "mousemove", this.onMouseMove); - event.addListener(editor.renderer.content, "mouseout", this.onMouseOut); -} - -oop.inherits(TokenTooltip, Tooltip); - -(function(){ - this.token = {}; - this.range = new Range(); +class TokenTooltip extends Tooltip { + constructor(editor) { + if (editor.tokenTooltip) + return; + super(editor.container); + editor.tokenTooltip = this; + this.editor = editor; + + this.update = this.update.bind(this); + this.onMouseMove = this.onMouseMove.bind(this); + this.onMouseOut = this.onMouseOut.bind(this); + event.addListener(editor.renderer.scroller, "mousemove", this.onMouseMove); + event.addListener(editor.renderer.content, "mouseout", this.onMouseOut); + } + token = {}; - this.update = function() { + range = new Range(); + + update() { this.$timer = null; var r = this.editor.renderer; @@ -105,6 +72,9 @@ oop.inherits(TokenTooltip, Tooltip); this.height = this.getHeight(); this.tokenText = tokenText; } + if (!this.isOpen) { + this.setTheme(r.theme); + } this.show(null, this.x, this.y); @@ -114,7 +84,7 @@ oop.inherits(TokenTooltip, Tooltip); this.marker = session.addMarker(this.range, "ace_bracket", "text"); }; - this.onMouseMove = function(e) { + onMouseMove(e) { this.x = e.clientX; this.y = e.clientY; if (this.isOpen) { @@ -125,7 +95,7 @@ oop.inherits(TokenTooltip, Tooltip); this.$timer = setTimeout(this.update, 100); }; - this.onMouseOut = function(e) { + onMouseOut(e) { if (e && e.currentTarget.contains(e.relatedTarget)) return; this.hide(); @@ -133,7 +103,7 @@ oop.inherits(TokenTooltip, Tooltip); this.$timer = clearTimeout(this.$timer); }; - this.setPosition = function(x, y) { + setPosition(x, y) { if (x + 10 + this.width > this.maxWidth) x = window.innerWidth - this.width - 10; if (y > window.innerHeight * 0.75 || y + 20 + this.height > this.maxHeight) @@ -142,15 +112,13 @@ oop.inherits(TokenTooltip, Tooltip); Tooltip.prototype.setPosition.call(this, x + 10, y + 20); }; - this.destroy = function() { + destroy() { this.onMouseOut(); event.removeListener(this.editor.renderer.scroller, "mousemove", this.onMouseMove); event.removeListener(this.editor.renderer.content, "mouseout", this.onMouseOut); delete this.editor.tokenTooltip; }; -}).call(TokenTooltip.prototype); +} exports.TokenTooltip = TokenTooltip; - -}); diff --git a/demo/kitchen-sink/util.js b/demo/kitchen-sink/util.js index c192df28721..544050a362f 100644 --- a/demo/kitchen-sink/util.js +++ b/demo/kitchen-sink/util.js @@ -1,34 +1,3 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { "use strict"; var dom = require("ace/lib/dom"); @@ -80,7 +49,9 @@ exports.createSplitEditor = function(el) { var split = {$container: el}; split.editor0 = split[0] = new Editor(new Renderer(e0)); + split.editor0.session.setUndoManager(new UndoManager()); split.editor1 = split[1] = new Editor(new Renderer(e1)); + split.editor1.session.setUndoManager(new UndoManager()); split.splitter = s; s.ratio = 0.5; @@ -251,6 +222,3 @@ function dropdown(values) { return elt("optgroup", {"label": i}, optgroup(values[i])); }); } - - -}); diff --git a/demo/modelist.html b/demo/modelist.html index 9b4b6039193..e03cc988dc8 100644 --- a/demo/modelist.html +++ b/demo/modelist.html @@ -26,13 +26,13 @@ + + diff --git a/demo/show_own_source.js b/demo/show_own_source.js index a9e0ec69583..56a01f891f2 100644 --- a/demo/show_own_source.js +++ b/demo/show_own_source.js @@ -2,15 +2,66 @@ if (typeof ace == "undefined" && typeof require == "undefined") { document.body.innerHTML = "

couldn't find ace.js file,
" + "to build it run node Makefile.dryice.js full" } else if (typeof ace == "undefined" && typeof require != "undefined") { - require(["ace/ace"], setValue) + require(["ace/ace"], function() { + setValue(); + }); + require(["ace/config"], function() { + var config = require("ace/config"); + config.setLoader(function(moduleName, cb) { + require([moduleName], function(module) { + cb(null, module); + }); + }); + }) } else { require = ace.require; setValue() } function setValue() { - require("ace/lib/net").get(document.baseURI, function(t){ + require("ace/lib/net").get(document.baseURI, function(text) { var el = document.getElementById("editor"); - el.env.editor.setValue(t, 1); - }) -} \ No newline at end of file + if (el) el.env.editor.session.setValue(text); + }); + loadAceLinters(); +} + +function loadAceLinters() { + if (typeof define == "function" && define.amd) { + require([ + "https://mkslanc.github.io/ace-linters/build/ace-linters.js" + ], function(m) { + addLinters(m.LanguageProvider); + }); + } else { + require("ace/lib/net").loadScript( + "https://mkslanc.github.io/ace-linters/build/ace-linters.js", + function() { + addLinters(window.LanguageProvider); + } + ) + } + function addLinters(LanguageProvider) { + var languageProvider = LanguageProvider.fromCdn("https://mkslanc.github.io/ace-linters/build", { + functionality: { + hover: true, + completion: { + overwriteCompleters: false + }, + completionResolve: true, + format: true, + documentHighlights: true, + signatureHelp: false + } + }); + window.languageProvider = languageProvider; + document.querySelectorAll(".ace_editor").forEach(function(el) { + var editor = el.env && el.env.editor; + if (editor) { + editor.setOption("enableBasicAutocompletion", true) + languageProvider.registerEditor(editor); + } + }); + } +} + diff --git a/demo/static-highlighter.html b/demo/static-highlighter.html index 8e43789d10b..70a216e83c0 100644 --- a/demo/static-highlighter.html +++ b/demo/static-highlighter.html @@ -56,11 +56,11 @@

Client Side Syntax Highlighting

+ diff --git a/demo/static-highlighter/server.js b/demo/static-highlighter/server.js index ea8361d4062..a733d83b927 100644 --- a/demo/static-highlighter/server.js +++ b/demo/static-highlighter/server.js @@ -27,7 +27,9 @@ http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html; charset=utf-8"}); fs.readFile(path, "utf8", function(err, data) { if (err) data = err.message; + var t = Date.now(); var highlighted = highlighter.render(data, new JavaScriptMode(), theme); + console.log("Rendered " + (data.length/1000) + "kb in " + (Date.now() - t) + "ms"); res.end( '\n' + ' @@ -70,6 +75,39 @@ console.log(e.type, e.charCode, e.keyCode, e); } +addListener(canvas, "mousedown", function(e) { + text.focus(); + e.preventDefault(); +}, false); + +var pos; +addListener(canvas, "touchstart", function(e) { + text.value = "" + pos = e.touches[0] + text.focus(); +}, false); +addListener(canvas, "contextmenu", function(e) { + text.value = "xxxxx"; + var rect = canvas.getBoundingClientRect() + // text.selectionStart = 0 + // text.selectionEnd = 20 + text.style.opacity = 0 + text.style.top = pos.clientY - 15 - rect.top + "px" + text.style.left = pos.clientX - 15 - rect.left + "px" + // canvas.style.fontSize = "300px" + // text.readOnly = true + // text.focus(); + text.style.width = "50px" + text.style.height = "50px" + text.select(); + setTimeout(function() { + text.readOnly = false + // text.style.top = pos.clientY - 5 + "px" + // text.style.left = pos.clientY - 5 + "px" + }, 100) + //e.preventDefault(); +}, false); + addListener(text, "keydown", logKey, false); addListener(text, "keyup", logKey, false); addListener(text, "keypress", logKey, false); @@ -78,8 +116,9 @@ console.log(e.type, e.data, e); }, false); +var i = 0; function fillSelection() { - text.value = "Juhu Kinners"; + text.value = "Juhu Kinners " + (i++); text.select(); } diff --git a/index.html b/index.html index 145b727b3f4..a7733c1e4a0 100644 --- a/index.html +++ b/index.html @@ -3,9 +3,8 @@ Ace - The High Performance Code Editor for the Web - - - + + @@ -17,7 +16,7 @@ - Fork me on GitHub + Fork me on GitHub
@@ -26,8 +25,8 @@

The high performance code editor for the web.

@@ -48,13 +47,13 @@

The high performance code ed
                             <a href=Syntax Highlighters
  • - API Reference + API Reference
  • Real World Users
  • - Support + Try
  • @@ -86,7 +85,7 @@

    Built for Code

    Looking for a more full-featured demo? Check out the - kitchen sink. + kitchen sink.

    Features

      @@ -133,11 +132,16 @@

      History

      Related Projects

      +

      Getting Help

      +

      Embedding Ace in Your Site

      @@ -182,7 +186,8 @@

      Loading Ace from a Local URL

      one of src* subdirectories somewhere into your project, or use RequireJS to load the contents of lib/ace folder as ace:

      -

      The packaged version can also be loaded from CDN's such as jsDelivr or cdnjs. +

      Loading Ace from a CDN

      +

      The packaged version can also be loaded from CDN's such as jsDelivr or cdnjs.

      @@ -216,11 +221,13 @@

      Configuring the editor

      Changing the size of the editor

      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:

      editor.resize()
      -

      if you want editor to change it's size based on contents, use maxLines option as shown in https://ace.c9.io/demo/autoresize.html

      +

      if you want editor to change it's size based on contents, use maxLines option as shown in https://ace.c9.io/demo/autoresize.html

      Setting Themes

      Themes are loaded on demand; all you have to do is pass the string name:

      editor.setTheme("ace/theme/twilight");
      -

      > See all themes

      +

      > See all themes. + Or use themelist extension to get the list of available themes at runtime. +

      Setting the Programming Language Mode

      By default, the editor supports plain text mode. All other language modes are available as separate modules, loaded on demand like this:

      editor.session.setMode("ace/mode/javascript");
      @@ -230,14 +237,14 @@

      One Editor, Multiple Sessions

      session, store it in a var, and set the editor to another session (e.g. a tabbed editor).

      You might accomplish this like so:

      -
      var EditSession = require("ace/edit_session").EditSession;
      -var js = new EditSession("some js code");
      -var css = new EditSession(["some", "css", "code here"]);
      +                                
      var js = ace.createEditSession("some js code");
      +var css = ace.createEditSession(["some", "css", "code here"]);
       // and then to load document into editor, just call
       editor.setSession(js);

      Common Operations

      Set and get content:

      editor.setValue("the new text here");
      +editor.setValue("text2", -1); // set value and move cursor to the start of the text
       editor.session.setValue("the new text here"); // set value and reset undo history
       editor.getValue(); // or session.getValue

      Get selected text:

      @@ -276,7 +283,13 @@

      Using undo manager

      editor.insertSnippet("a$0b"); 
       editor.session.markUndoGroup(); 
       editor.insertSnippet("x$0y");
      -

      To implement undo/redo buttons see https://ace.c9.io/demo/toolbar.html

      +

      To disable undo of a an edit in a collaborative editor

      +
      var rev = session.$undoManager.startNewGroup(); // start new undo group
      +... // apply the edit 
      +session.$undoManager.markIgnored(rev); // mark the new group as ignored
      + + +

      To implement undo/redo buttons see https://ace.c9.io/demo/toolbar.html

      Searching

      editor.find('needle',{
      @@ -346,8 +359,21 @@ 

      Adding New Commands and Keybindings

      exec: function(editor) { //... }, - readOnly: true // false if this command should not apply in readOnly mode + readOnly: true, // false if this command should not apply in readOnly mode + // multiSelectAction: "forEach", optional way to control behavior with multiple cursors + // scrollIntoView: "cursor", control how cursor is scolled into view after the command });
      +

      Configure dynamic loading of modes and themes

      +

      By default ace detcts the url for dynamic loading by finding the script node for ace.js. + 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

      +
      ace.config.set("basePath", "https://url.to.a/folder/that/contains-ace-modes");
      +

      Path for one module alone can be configured with:

      +
      ace.config.setModuleUrl("ace/theme/textmate", "url for textmate.js");
      +

      When using ace with webpack, it is possible to configure paths for all submodules using

      +
      require("ace-builds/esm-resolver"); // for new bundlers: webpack 5, rollup, vite
      + For webpack 4 use +
      require("ace-builds/webpack-resolver"); 
      +

      which depends on file-loader

      Creating a Syntax Highlighter for Ace

      @@ -812,9 +838,9 @@

      Projects Using Ace

      Codiad
    • - - Plunker + + aFreeTools
    • Projects Using Ace style="left: 18px; top: 6px;"> MODX
    • -
    • - - Chrome Dev Editor -
    • @@ -863,52 +884,19 @@

      Projects Using Ace

      Code Combat
    • -
    • - - Repl.it + + Papeeria
    • CodinGame
    • -
    • - - ProcessWire -
    • -
    • - - Crunch -
    • -
    • - - Drive Notepad -
    • -
    • - - Textor -
    • Dillinger
    • -
    • - - Evaluzio -
    • -
    • - - CodeHelper -
    • Edicy @@ -917,19 +905,11 @@

      Projects Using Ace

      pixelJET
    • -
    • - - BonsaiJS playground -
    • Simply Text
    • -
    • - - ShareLaTeX -
    • ACEView @@ -947,22 +927,6 @@

      Projects Using Ace

      Debuggex
    • -
    • -
      S
      - Slim Text -
    • -
    • - - Decor -
    • -
    • - - Papeeria -
    • - - - - - + + + + diff --git a/kitchen-sink.html b/kitchen-sink.html index c4be9da5a9f..73d0ccc56ec 100644 --- a/kitchen-sink.html +++ b/kitchen-sink.html @@ -3,36 +3,32 @@ + Ace Kitchen Sink - - -
      - - +
      +
      +
      +
      +
      + -
      -
      +
      + @@ -48,22 +50,67 @@ + + - - " - ], new PHPMode()); - s.setUseSoftTabs(false); - - beautify.beautify(s); - assert.equal(s.getValue(), "\n" - + ""); - - next(); - }, - - "test beautify js array of objects": function(next) { - var s = new EditSession([ - "" - ], new PHPMode()); - s.setUseSoftTabs(false); - - beautify.beautify(s); - assert.equal(s.getValue(), ""); - - next(); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/ext/elastic_tabstops_lite.js b/lib/ace/ext/elastic_tabstops_lite.js deleted file mode 100644 index 0f89423a85a..00000000000 --- a/lib/ace/ext/elastic_tabstops_lite.js +++ /dev/null @@ -1,318 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var ElasticTabstopsLite = function(editor) { - this.$editor = editor; - var self = this; - var changedRows = []; - var recordChanges = false; - this.onAfterExec = function() { - recordChanges = false; - self.processRows(changedRows); - changedRows = []; - }; - this.onExec = function() { - recordChanges = true; - }; - this.onChange = function(delta) { - if (recordChanges) { - if (changedRows.indexOf(delta.start.row) == -1) - changedRows.push(delta.start.row); - if (delta.end.row != delta.start.row) - changedRows.push(delta.end.row); - } - }; -}; - -(function() { - this.processRows = function(rows) { - this.$inChange = true; - var checkedRows = []; - - for (var r = 0, rowCount = rows.length; r < rowCount; r++) { - var row = rows[r]; - - if (checkedRows.indexOf(row) > -1) - continue; - - var cellWidthObj = this.$findCellWidthsForBlock(row); - var cellWidths = this.$setBlockCellWidthsToMax(cellWidthObj.cellWidths); - var rowIndex = cellWidthObj.firstRow; - - for (var w = 0, l = cellWidths.length; w < l; w++) { - var widths = cellWidths[w]; - checkedRows.push(rowIndex); - this.$adjustRow(rowIndex, widths); - rowIndex++; - } - } - this.$inChange = false; - }; - - this.$findCellWidthsForBlock = function(row) { - var cellWidths = [], widths; - - // starting row and backward - var rowIter = row; - while (rowIter >= 0) { - widths = this.$cellWidthsForRow(rowIter); - if (widths.length == 0) - break; - - cellWidths.unshift(widths); - rowIter--; - } - var firstRow = rowIter + 1; - - // forward (not including starting row) - rowIter = row; - var numRows = this.$editor.session.getLength(); - - while (rowIter < numRows - 1) { - rowIter++; - - widths = this.$cellWidthsForRow(rowIter); - if (widths.length == 0) - break; - - cellWidths.push(widths); - } - - return { cellWidths: cellWidths, firstRow: firstRow }; - }; - - this.$cellWidthsForRow = function(row) { - var selectionColumns = this.$selectionColumnsForRow(row); - // todo: support multicursor - - var tabs = [-1].concat(this.$tabsForRow(row)); - var widths = tabs.map(function(el) { return 0; } ).slice(1); - var line = this.$editor.session.getLine(row); - - for (var i = 0, len = tabs.length - 1; i < len; i++) { - var leftEdge = tabs[i]+1; - var rightEdge = tabs[i+1]; - - var rightmostSelection = this.$rightmostSelectionInCell(selectionColumns, rightEdge); - var cell = line.substring(leftEdge, rightEdge); - widths[i] = Math.max(cell.replace(/\s+$/g,'').length, rightmostSelection - leftEdge); - } - - return widths; - }; - - this.$selectionColumnsForRow = function(row) { - var selections = [], cursor = this.$editor.getCursorPosition(); - if (this.$editor.session.getSelection().isEmpty()) { - // todo: support multicursor - if (row == cursor.row) - selections.push(cursor.column); - } - - return selections; - }; - - this.$setBlockCellWidthsToMax = function(cellWidths) { - var startingNewBlock = true, blockStartRow, blockEndRow, maxWidth; - var columnInfo = this.$izip_longest(cellWidths); - - for (var c = 0, l = columnInfo.length; c < l; c++) { - var column = columnInfo[c]; - if (!column.push) { - console.error(column); - continue; - } - // add an extra None to the end so that the end of the column automatically - // finishes a block - column.push(NaN); - - for (var r = 0, s = column.length; r < s; r++) { - var width = column[r]; - if (startingNewBlock) { - blockStartRow = r; - maxWidth = 0; - startingNewBlock = false; - } - if (isNaN(width)) { - // block ended - blockEndRow = r; - - for (var j = blockStartRow; j < blockEndRow; j++) { - cellWidths[j][c] = maxWidth; - } - startingNewBlock = true; - } - - maxWidth = Math.max(maxWidth, width); - } - } - - return cellWidths; - }; - - this.$rightmostSelectionInCell = function(selectionColumns, cellRightEdge) { - var rightmost = 0; - - if (selectionColumns.length) { - var lengths = []; - for (var s = 0, length = selectionColumns.length; s < length; s++) { - if (selectionColumns[s] <= cellRightEdge) - lengths.push(s); - else - lengths.push(0); - } - rightmost = Math.max.apply(Math, lengths); - } - - return rightmost; - }; - - this.$tabsForRow = function(row) { - var rowTabs = [], line = this.$editor.session.getLine(row), - re = /\t/g, match; - - while ((match = re.exec(line)) != null) { - rowTabs.push(match.index); - } - - return rowTabs; - }; - - this.$adjustRow = function(row, widths) { - var rowTabs = this.$tabsForRow(row); - - if (rowTabs.length == 0) - return; - - var bias = 0, location = -1; - - // this always only contains two elements, so we're safe in the loop below - var expandedSet = this.$izip(widths, rowTabs); - - for (var i = 0, l = expandedSet.length; i < l; i++) { - var w = expandedSet[i][0], it = expandedSet[i][1]; - location += 1 + w; - it += bias; - var difference = location - it; - - if (difference == 0) - continue; - - var partialLine = this.$editor.session.getLine(row).substr(0, it ); - var strippedPartialLine = partialLine.replace(/\s*$/g, ""); - var ispaces = partialLine.length - strippedPartialLine.length; - - if (difference > 0) { - // put the spaces after the tab and then delete the tab, so any insertion - // points behave as expected - this.$editor.session.getDocument().insertInLine({row: row, column: it + 1}, Array(difference + 1).join(" ") + "\t"); - this.$editor.session.getDocument().removeInLine(row, it, it + 1); - - bias += difference; - } - - if (difference < 0 && ispaces >= -difference) { - this.$editor.session.getDocument().removeInLine(row, it + difference, it); - bias += difference; - } - } - }; - - // the is a (naive) Python port--but works for these purposes - this.$izip_longest = function(iterables) { - if (!iterables[0]) - return []; - var longest = iterables[0].length; - var iterablesLength = iterables.length; - - for (var i = 1; i < iterablesLength; i++) { - var iLength = iterables[i].length; - if (iLength > longest) - longest = iLength; - } - - var expandedSet = []; - - for (var l = 0; l < longest; l++) { - var set = []; - for (var i = 0; i < iterablesLength; i++) { - if (iterables[i][l] === "") - set.push(NaN); - else - set.push(iterables[i][l]); - } - - expandedSet.push(set); - } - - - return expandedSet; - }; - - // an even more (naive) Python port - this.$izip = function(widths, tabs) { - // grab the shorter size - var size = widths.length >= tabs.length ? tabs.length : widths.length; - - var expandedSet = []; - for (var i = 0; i < size; i++) { - var set = [ widths[i], tabs[i] ]; - expandedSet.push(set); - } - return expandedSet; - }; - -}).call(ElasticTabstopsLite.prototype); - -exports.ElasticTabstopsLite = ElasticTabstopsLite; - -var Editor = require("../editor").Editor; -require("../config").defineOptions(Editor.prototype, "editor", { - useElasticTabstops: { - set: function(val) { - if (val) { - if (!this.elasticTabstops) - this.elasticTabstops = new ElasticTabstopsLite(this); - this.commands.on("afterExec", this.elasticTabstops.onAfterExec); - this.commands.on("exec", this.elasticTabstops.onExec); - this.on("change", this.elasticTabstops.onChange); - } else if (this.elasticTabstops) { - this.commands.removeListener("afterExec", this.elasticTabstops.onAfterExec); - this.commands.removeListener("exec", this.elasticTabstops.onExec); - this.removeListener("change", this.elasticTabstops.onChange); - } - } - } -}); - -}); \ No newline at end of file diff --git a/lib/ace/ext/error_marker.js b/lib/ace/ext/error_marker.js deleted file mode 100644 index 03baa119b2e..00000000000 --- a/lib/ace/ext/error_marker.js +++ /dev/null @@ -1,217 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; -var LineWidgets = require("../line_widgets").LineWidgets; -var dom = require("../lib/dom"); -var Range = require("../range").Range; - -function binarySearch(array, needle, comparator) { - var first = 0; - var last = array.length - 1; - - while (first <= last) { - var mid = (first + last) >> 1; - var c = comparator(needle, array[mid]); - if (c > 0) - first = mid + 1; - else if (c < 0) - last = mid - 1; - else - return mid; - } - - // Return the nearest lesser index, "-1" means "0, "-2" means "1", etc. - return -(first + 1); -} - -function findAnnotations(session, row, dir) { - var annotations = session.getAnnotations().sort(Range.comparePoints); - if (!annotations.length) - return; - - var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints); - if (i < 0) - i = -i - 1; - - if (i >= annotations.length) - i = dir > 0 ? 0 : annotations.length - 1; - else if (i === 0 && dir < 0) - i = annotations.length - 1; - - var annotation = annotations[i]; - if (!annotation || !dir) - return; - - if (annotation.row === row) { - do { - annotation = annotations[i += dir]; - } while (annotation && annotation.row === row); - if (!annotation) - return annotations.slice(); - } - - - var matched = []; - row = annotation.row; - do { - matched[dir < 0 ? "unshift" : "push"](annotation); - annotation = annotations[i += dir]; - } while (annotation && annotation.row == row); - return matched.length && matched; -} - -exports.showErrorMarker = function(editor, dir) { - var session = editor.session; - if (!session.widgetManager) { - session.widgetManager = new LineWidgets(session); - session.widgetManager.attach(editor); - } - - var pos = editor.getCursorPosition(); - var row = pos.row; - var oldWidget = session.widgetManager.getWidgetsAtRow(row).filter(function(w) { - return w.type == "errorMarker"; - })[0]; - if (oldWidget) { - oldWidget.destroy(); - } else { - row -= dir; - } - var annotations = findAnnotations(session, row, dir); - var gutterAnno; - if (annotations) { - var annotation = annotations[0]; - pos.column = (annotation.pos && typeof annotation.column != "number" - ? annotation.pos.sc - : annotation.column) || 0; - pos.row = annotation.row; - gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row]; - } else if (oldWidget) { - return; - } else { - gutterAnno = { - text: ["Looks good!"], - className: "ace_ok" - }; - } - editor.session.unfold(pos.row); - editor.selection.moveToPosition(pos); - - var w = { - row: pos.row, - fixedWidth: true, - coverGutter: true, - el: dom.createElement("div"), - type: "errorMarker" - }; - var el = w.el.appendChild(dom.createElement("div")); - var arrow = w.el.appendChild(dom.createElement("div")); - arrow.className = "error_widget_arrow " + gutterAnno.className; - - var left = editor.renderer.$cursorLayer - .getPixelPosition(pos).left; - arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px"; - - w.el.className = "error_widget_wrapper"; - el.className = "error_widget " + gutterAnno.className; - el.innerHTML = gutterAnno.text.join("
      "); - - el.appendChild(dom.createElement("div")); - - var kb = function(_, hashId, keyString) { - if (hashId === 0 && (keyString === "esc" || keyString === "return")) { - w.destroy(); - return {command: "null"}; - } - }; - - w.destroy = function() { - if (editor.$mouseHandler.isMousePressed) - return; - editor.keyBinding.removeKeyboardHandler(kb); - session.widgetManager.removeLineWidget(w); - editor.off("changeSelection", w.destroy); - editor.off("changeSession", w.destroy); - editor.off("mouseup", w.destroy); - editor.off("change", w.destroy); - }; - - editor.keyBinding.addKeyboardHandler(kb); - editor.on("changeSelection", w.destroy); - editor.on("changeSession", w.destroy); - editor.on("mouseup", w.destroy); - editor.on("change", w.destroy); - - editor.session.widgetManager.addLineWidget(w); - - w.el.onmousedown = editor.focus.bind(editor); - - editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight}); -}; - - -dom.importCssString("\ - .error_widget_wrapper {\ - background: inherit;\ - color: inherit;\ - border:none\ - }\ - .error_widget {\ - border-top: solid 2px;\ - border-bottom: solid 2px;\ - margin: 5px 0;\ - padding: 10px 40px;\ - white-space: pre-wrap;\ - }\ - .error_widget.ace_error, .error_widget_arrow.ace_error{\ - border-color: #ff5a5a\ - }\ - .error_widget.ace_warning, .error_widget_arrow.ace_warning{\ - border-color: #F1D817\ - }\ - .error_widget.ace_info, .error_widget_arrow.ace_info{\ - border-color: #5a5a5a\ - }\ - .error_widget.ace_ok, .error_widget_arrow.ace_ok{\ - border-color: #5aaa5a\ - }\ - .error_widget_arrow {\ - position: absolute;\ - border: solid 5px;\ - border-top-color: transparent!important;\ - border-right-color: transparent!important;\ - border-left-color: transparent!important;\ - top: -5px;\ - }\ -", ""); - -}); \ No newline at end of file diff --git a/lib/ace/ext/keybinding_menu.js b/lib/ace/ext/keybinding_menu.js deleted file mode 100644 index 38e578d81f4..00000000000 --- a/lib/ace/ext/keybinding_menu.js +++ /dev/null @@ -1,86 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl - * All rights reserved. - * - * Contributed to Ajax.org under the BSD license. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ -/*global define, require */ - -/** - * Show Keyboard Shortcuts - * @fileOverview Show Keyboard Shortcuts
      - * Generates a menu which displays the keyboard shortcuts. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - */ - -define(function(require, exports, module) { - "use strict"; - var Editor = require("ace/editor").Editor; - /** - * Generates a menu which displays the keyboard shortcuts. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - * @param {ace.Editor} editor An instance of the ace editor. - */ - function showKeyboardShortcuts (editor) { - // make sure the menu isn't open already. - if(!document.getElementById('kbshortcutmenu')) { - var overlayPage = require('./menu_tools/overlay_page').overlayPage; - var getEditorKeybordShortcuts = require('./menu_tools/get_editor_keyboard_shortcuts').getEditorKeybordShortcuts; - var kb = getEditorKeybordShortcuts(editor); - var el = document.createElement('div'); - var commands = kb.reduce(function(previous, current) { - return previous + '
      ' - + current.command + ' : ' - + '' + current.key + '
      '; - }, ''); - - el.id = 'kbshortcutmenu'; - el.innerHTML = '

      Keyboard Shortcuts

      ' + commands + '
      '; - overlayPage(editor, el, '0', '0', '0', null); - } - } - module.exports.init = function(editor) { - Editor.prototype.showKeyboardShortcuts = function() { - showKeyboardShortcuts(this); - }; - editor.commands.addCommands([{ - name: "showKeyboardShortcuts", - bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"}, - exec: function(editor, line) { - editor.showKeyboardShortcuts(); - } - }]); - }; - -}); \ No newline at end of file diff --git a/lib/ace/ext/language_tools.js b/lib/ace/ext/language_tools.js deleted file mode 100644 index 5c942d8d8ce..00000000000 --- a/lib/ace/ext/language_tools.js +++ /dev/null @@ -1,218 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var snippetManager = require("../snippets").snippetManager; -var Autocomplete = require("../autocomplete").Autocomplete; -var config = require("../config"); -var lang = require("../lib/lang"); -var util = require("../autocomplete/util"); - -var textCompleter = require("../autocomplete/text_completer"); -var keyWordCompleter = { - getCompletions: function(editor, session, pos, prefix, callback) { - if (session.$mode.completer) { - return session.$mode.completer.getCompletions(editor, session, pos, prefix, callback); - } - var state = editor.session.getState(pos.row); - var completions = session.$mode.getCompletions(state, session, pos, prefix); - callback(null, completions); - } -}; - -var snippetCompleter = { - getCompletions: function(editor, session, pos, prefix, callback) { - var scopes = []; - - // set scope to html-tag if we're inside an html tag - var token = session.getTokenAt(pos.row, pos.column); - if (token && token.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\.xml$/)) - scopes.push('html-tag'); - else - scopes = snippetManager.getActiveScopes(editor); - - var snippetMap = snippetManager.snippetMap; - var completions = []; - scopes.forEach(function(scope) { - var snippets = snippetMap[scope] || []; - for (var i = snippets.length; i--;) { - var s = snippets[i]; - var caption = s.name || s.tabTrigger; - if (!caption) - continue; - completions.push({ - caption: caption, - snippet: s.content, - meta: s.tabTrigger && !s.name ? s.tabTrigger + "\u21E5 " : "snippet", - type: "snippet" - }); - } - }, this); - callback(null, completions); - }, - getDocTooltip: function(item) { - if (item.type == "snippet" && !item.docHTML) { - item.docHTML = [ - "", lang.escapeHTML(item.caption), "", "
      ", - lang.escapeHTML(item.snippet) - ].join(""); - } - } -}; - -var completers = [snippetCompleter, textCompleter, keyWordCompleter]; -// Modifies list of default completers -exports.setCompleters = function(val) { - completers.length = 0; - if (val) completers.push.apply(completers, val); -}; -exports.addCompleter = function(completer) { - completers.push(completer); -}; - -// Exports existing completer so that user can construct his own set of completers. -exports.textCompleter = textCompleter; -exports.keyWordCompleter = keyWordCompleter; -exports.snippetCompleter = snippetCompleter; - -var expandSnippet = { - name: "expandSnippet", - exec: function(editor) { - return snippetManager.expandWithTab(editor); - }, - bindKey: "Tab" -}; - -var onChangeMode = function(e, editor) { - loadSnippetsForMode(editor.session.$mode); -}; - -var loadSnippetsForMode = function(mode) { - var id = mode.$id; - if (!snippetManager.files) - snippetManager.files = {}; - loadSnippetFile(id); - if (mode.modes) - mode.modes.forEach(loadSnippetsForMode); -}; - -var loadSnippetFile = function(id) { - if (!id || snippetManager.files[id]) - return; - var snippetFilePath = id.replace("mode", "snippets"); - snippetManager.files[id] = {}; - config.loadModule(snippetFilePath, function(m) { - if (m) { - snippetManager.files[id] = m; - if (!m.snippets && m.snippetText) - m.snippets = snippetManager.parseSnippetFile(m.snippetText); - snippetManager.register(m.snippets || [], m.scope); - if (m.includeScopes) { - snippetManager.snippetMap[m.scope].includeScopes = m.includeScopes; - m.includeScopes.forEach(function(x) { - loadSnippetFile("ace/mode/" + x); - }); - } - } - }); -}; - -var doLiveAutocomplete = function(e) { - var editor = e.editor; - var hasCompleter = editor.completer && editor.completer.activated; - - // We don't want to autocomplete with no prefix - if (e.command.name === "backspace") { - if (hasCompleter && !util.getCompletionPrefix(editor)) - editor.completer.detach(); - } - else if (e.command.name === "insertstring") { - var prefix = util.getCompletionPrefix(editor); - // Only autocomplete if there's a prefix that can be matched - if (prefix && !hasCompleter) { - if (!editor.completer) { - // Create new autocompleter - editor.completer = new Autocomplete(); - } - // Disable autoInsert - editor.completer.autoInsert = false; - editor.completer.showPopup(editor); - } - } -}; - -var Editor = require("../editor").Editor; -require("../config").defineOptions(Editor.prototype, "editor", { - enableBasicAutocompletion: { - set: function(val) { - if (val) { - if (!this.completers) - this.completers = Array.isArray(val)? val: completers; - this.commands.addCommand(Autocomplete.startCommand); - } else { - this.commands.removeCommand(Autocomplete.startCommand); - } - }, - value: false - }, - /** - * Enable live autocomplete. If the value is an array, it is assumed to be an array of completers - * and will use them instead of the default completers. - */ - enableLiveAutocompletion: { - set: function(val) { - if (val) { - if (!this.completers) - this.completers = Array.isArray(val)? val: completers; - // On each change automatically trigger the autocomplete - this.commands.on('afterExec', doLiveAutocomplete); - } else { - this.commands.removeListener('afterExec', doLiveAutocomplete); - } - }, - value: false - }, - enableSnippets: { - set: function(val) { - if (val) { - this.commands.addCommand(expandSnippet); - this.on("changeMode", onChangeMode); - onChangeMode(null, this); - } else { - this.commands.removeCommand(expandSnippet); - this.off("changeMode", onChangeMode); - } - }, - value: false - } -}); -}); diff --git a/lib/ace/ext/linking.js b/lib/ace/ext/linking.js deleted file mode 100644 index 836f9f6fd56..00000000000 --- a/lib/ace/ext/linking.js +++ /dev/null @@ -1,87 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var Editor = require("ace/editor").Editor; - -require("../config").defineOptions(Editor.prototype, "editor", { - enableLinking: { - set: function(val) { - if (val) { - this.on("click", onClick); - this.on("mousemove", onMouseMove); - } else { - this.off("click", onClick); - this.off("mousemove", onMouseMove); - } - }, - value: false - } -}); - -exports.previousLinkingHover = false; - -function onMouseMove(e) { - var editor = e.editor; - var ctrl = e.getAccelKey(); - - if (ctrl) { - var editor = e.editor; - var docPos = e.getDocumentPosition(); - var session = editor.session; - var token = session.getTokenAt(docPos.row, docPos.column); - - if (exports.previousLinkingHover && exports.previousLinkingHover != token) { - editor._emit("linkHoverOut"); - } - editor._emit("linkHover", {position: docPos, token: token}); - exports.previousLinkingHover = token; - } else if (exports.previousLinkingHover) { - editor._emit("linkHoverOut"); - exports.previousLinkingHover = false; - } -} - -function onClick(e) { - var ctrl = e.getAccelKey(); - var button = e.getButton(); - - if (button == 0 && ctrl) { - var editor = e.editor; - var docPos = e.getDocumentPosition(); - var session = editor.session; - var token = session.getTokenAt(docPos.row, docPos.column); - - editor._emit("linkClick", {position: docPos, token: token}); - } -} - -}); diff --git a/lib/ace/ext/menu_tools/get_editor_keyboard_shortcuts.js b/lib/ace/ext/menu_tools/get_editor_keyboard_shortcuts.js deleted file mode 100644 index c3f7a627f83..00000000000 --- a/lib/ace/ext/menu_tools/get_editor_keyboard_shortcuts.js +++ /dev/null @@ -1,91 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl - * All rights reserved. - * - * Contributed to Ajax.org under the BSD license. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ -/*global define, require */ - -/** - * Get Editor Keyboard Shortcuts - * @fileOverview Get Editor Keyboard Shortcuts
      - * Gets a map of keyboard shortcuts to command names for the current platform. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - */ - -define(function(require, exports, module) { -"use strict"; -var keys = require("../../lib/keys"); - -/** - * Gets a map of keyboard shortcuts to command names for the current platform. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - * @param {ace.Editor} editor An editor instance. - * @returns {Array} Returns an array of objects representing the keyboard - * shortcuts for the given editor. - * @example - * var getKbShortcuts = require('./get_keyboard_shortcuts'); - * console.log(getKbShortcuts(editor)); - * // [ - * // {'command' : aCommand, 'key' : 'Control-d'}, - * // {'command' : aCommand, 'key' : 'Control-d'} - * // ] - */ -module.exports.getEditorKeybordShortcuts = function(editor) { - var KEY_MODS = keys.KEY_MODS; - var keybindings = []; - var commandMap = {}; - editor.keyBinding.$handlers.forEach(function(handler) { - var ckb = handler.commandKeyBinding; - for (var i in ckb) { - var key = i.replace(/(^|-)\w/g, function(x) { return x.toUpperCase(); }); - var commands = ckb[i]; - if (!Array.isArray(commands)) - commands = [commands]; - commands.forEach(function(command) { - if (typeof command != "string") - command = command.name; - if (commandMap[command]) { - commandMap[command].key += "|" + key; - } else { - commandMap[command] = {key: key, command: command}; - keybindings.push(commandMap[command]); - } - }); - } - }); - return keybindings; -}; - -}); \ No newline at end of file diff --git a/lib/ace/ext/menu_tools/overlay_page.js b/lib/ace/ext/menu_tools/overlay_page.js deleted file mode 100644 index bf985e29c6a..00000000000 --- a/lib/ace/ext/menu_tools/overlay_page.js +++ /dev/null @@ -1,116 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl - * All rights reserved. - * - * Contributed to Ajax.org under the BSD license. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ -/*global define, require */ - -/** - * Overlay Page - * @fileOverview Overlay Page
      - * Generates an overlay for displaying menus. The overlay is an absolutely - * positioned div. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - */ - -define(function(require, exports, module) { -'use strict'; -var dom = require("../../lib/dom"); -var cssText = require("../../requirejs/text!./settings_menu.css"); -dom.importCssString(cssText); - -/** - * Generates an overlay for displaying menus. The overlay is an absolutely - * positioned div. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - * @param {DOMElement} contentElement Any element which may be presented inside - * a div. - * @param {string|number} top absolute position value. - * @param {string|number} right absolute position value. - * @param {string|number} bottom absolute position value. - * @param {string|number} left absolute position value. - */ -module.exports.overlayPage = function overlayPage(editor, contentElement, top, right, bottom, left) { - top = top ? 'top: ' + top + ';' : ''; - bottom = bottom ? 'bottom: ' + bottom + ';' : ''; - right = right ? 'right: ' + right + ';' : ''; - left = left ? 'left: ' + left + ';' : ''; - - var closer = document.createElement('div'); - var contentContainer = document.createElement('div'); - - function documentEscListener(e) { - if (e.keyCode === 27) { - closer.click(); - } - } - - closer.style.cssText = 'margin: 0; padding: 0; ' + - 'position: fixed; top:0; bottom:0; left:0; right:0;' + - 'z-index: 9990; ' + - 'background-color: rgba(0, 0, 0, 0.3);'; - closer.addEventListener('click', function() { - document.removeEventListener('keydown', documentEscListener); - closer.parentNode.removeChild(closer); - editor.focus(); - closer = null; - }); - // click closer if esc key is pressed - document.addEventListener('keydown', documentEscListener); - - contentContainer.style.cssText = top + right + bottom + left; - contentContainer.addEventListener('click', function(e) { - e.stopPropagation(); - }); - - var wrapper = dom.createElement("div"); - wrapper.style.position = "relative"; - - var closeButton = dom.createElement("div"); - closeButton.className = "ace_closeButton"; - closeButton.addEventListener('click', function() { - closer.click(); - }); - - wrapper.appendChild(closeButton); - contentContainer.appendChild(wrapper); - - contentContainer.appendChild(contentElement); - closer.appendChild(contentContainer); - document.body.appendChild(closer); - editor.blur(); -}; - -}); \ No newline at end of file diff --git a/lib/ace/ext/menu_tools/settings_menu.css b/lib/ace/ext/menu_tools/settings_menu.css deleted file mode 100644 index 8961e430f62..00000000000 --- a/lib/ace/ext/menu_tools/settings_menu.css +++ /dev/null @@ -1,64 +0,0 @@ -#ace_settingsmenu, #kbshortcutmenu { - background-color: #F7F7F7; - color: black; - box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55); - padding: 1em 0.5em 2em 1em; - overflow: auto; - position: absolute; - margin: 0; - bottom: 0; - right: 0; - top: 0; - z-index: 9991; - cursor: default; -} - -.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu { - box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25); - background-color: rgba(255, 255, 255, 0.6); - color: black; -} - -.ace_optionsMenuEntry:hover { - background-color: rgba(100, 100, 100, 0.1); - transition: all 0.3s -} - -.ace_closeButton { - background: rgba(245, 146, 146, 0.5); - border: 1px solid #F48A8A; - border-radius: 50%; - padding: 7px; - position: absolute; - right: -8px; - top: -8px; - z-index: 100000; -} -.ace_closeButton{ - background: rgba(245, 146, 146, 0.9); -} -.ace_optionsMenuKey { - color: darkslateblue; - font-weight: bold; -} -.ace_optionsMenuCommand { - color: darkcyan; - font-weight: normal; -} -.ace_optionsMenuEntry input, .ace_optionsMenuEntry button { - vertical-align: middle; -} - -.ace_optionsMenuEntry button[ace_selected_button=true] { - background: #e7e7e7; - box-shadow: 1px 0px 2px 0px #adadad inset; - border-color: #adadad; -} -.ace_optionsMenuEntry button { - background: white; - border: 1px solid lightgray; - margin: 0px; -} -.ace_optionsMenuEntry button:hover{ - background: #f0f0f0; -} \ No newline at end of file diff --git a/lib/ace/ext/modelist.js b/lib/ace/ext/modelist.js deleted file mode 100644 index 202ddcdad42..00000000000 --- a/lib/ace/ext/modelist.js +++ /dev/null @@ -1,227 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var modes = []; -/** - * Suggests a mode based on the file extension present in the given path - * @param {string} path The path to the file - * @returns {object} Returns an object containing information about the - * suggested mode. - */ -function getModeForPath(path) { - var mode = modesByName.text; - var fileName = path.split(/[\/\\]/).pop(); - for (var i = 0; i < modes.length; i++) { - if (modes[i].supportsFile(fileName)) { - mode = modes[i]; - break; - } - } - return mode; -} - -var Mode = function(name, caption, extensions) { - this.name = name; - this.caption = caption; - this.mode = "ace/mode/" + name; - this.extensions = extensions; - var re; - if (/\^/.test(extensions)) { - re = extensions.replace(/\|(\^)?/g, function(a, b){ - return "$|" + (b ? "^" : "^.*\\."); - }) + "$"; - } else { - re = "^.*\\.(" + extensions + ")$"; - } - - this.extRe = new RegExp(re, "gi"); -}; - -Mode.prototype.supportsFile = function(filename) { - return filename.match(this.extRe); -}; - -// todo firstlinematch -var supportedModes = { - ABAP: ["abap"], - ABC: ["abc"], - ActionScript:["as"], - ADA: ["ada|adb"], - Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"], - AsciiDoc: ["asciidoc|adoc"], - ASL: ["dsl|asl"], - Assembly_x86:["asm|a"], - AutoHotKey: ["ahk"], - BatchFile: ["bat|cmd"], - Bro: ["bro"], - C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp|ino"], - C9Search: ["c9search_results"], - Cirru: ["cirru|cr"], - Clojure: ["clj|cljs"], - Cobol: ["CBL|COB"], - coffee: ["coffee|cf|cson|^Cakefile"], - ColdFusion: ["cfm"], - CSharp: ["cs"], - Csound_Document: ["csd"], - Csound_Orchestra: ["orc"], - Csound_Score: ["sco"], - CSS: ["css"], - Curly: ["curly"], - D: ["d|di"], - Dart: ["dart"], - Diff: ["diff|patch"], - Dockerfile: ["^Dockerfile"], - Dot: ["dot"], - Drools: ["drl"], - Edifact: ["edi"], - Eiffel: ["e|ge"], - EJS: ["ejs"], - Elixir: ["ex|exs"], - Elm: ["elm"], - Erlang: ["erl|hrl"], - Forth: ["frt|fs|ldr|fth|4th"], - Fortran: ["f|f90"], - FSharp: ["fsi|fs|ml|mli|fsx|fsscript"], - FTL: ["ftl"], - Gcode: ["gcode"], - Gherkin: ["feature"], - Gitignore: ["^.gitignore"], - Glsl: ["glsl|frag|vert"], - Gobstones: ["gbs"], - golang: ["go"], - GraphQLSchema: ["gql"], - Groovy: ["groovy"], - HAML: ["haml"], - Handlebars: ["hbs|handlebars|tpl|mustache"], - Haskell: ["hs"], - Haskell_Cabal: ["cabal"], - haXe: ["hx"], - Hjson: ["hjson"], - HTML: ["html|htm|xhtml|vue|we|wpy"], - HTML_Elixir: ["eex|html.eex"], - HTML_Ruby: ["erb|rhtml|html.erb"], - INI: ["ini|conf|cfg|prefs"], - Io: ["io"], - Jack: ["jack"], - Jade: ["jade|pug"], - Java: ["java"], - JavaScript: ["js|jsm|jsx"], - JSON: ["json"], - JSONiq: ["jq"], - JSP: ["jsp"], - JSSM: ["jssm|jssm_state"], - JSX: ["jsx"], - Julia: ["jl"], - Kotlin: ["kt|kts"], - LaTeX: ["tex|latex|ltx|bib"], - LESS: ["less"], - Liquid: ["liquid"], - Lisp: ["lisp"], - LiveScript: ["ls"], - LogiQL: ["logic|lql"], - LSL: ["lsl"], - Lua: ["lua"], - LuaPage: ["lp"], - Lucene: ["lucene"], - Makefile: ["^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make"], - Markdown: ["md|markdown"], - Mask: ["mask"], - MATLAB: ["matlab"], - Maze: ["mz"], - MEL: ["mel"], - MIXAL: ["mixal"], - MUSHCode: ["mc|mush"], - MySQL: ["mysql"], - Nix: ["nix"], - NSIS: ["nsi|nsh"], - ObjectiveC: ["m|mm"], - OCaml: ["ml|mli"], - Pascal: ["pas|p"], - Perl: ["pl|pm"], - pgSQL: ["pgsql"], - PHP_Laravel_blade: ["blade.php"], - PHP: ["php|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module"], - Pig: ["pig"], - Powershell: ["ps1"], - Praat: ["praat|praatscript|psc|proc"], - Prolog: ["plg|prolog"], - Properties: ["properties"], - Protobuf: ["proto"], - Python: ["py"], - R: ["r"], - Razor: ["cshtml|asp"], - RDoc: ["Rd"], - Red: ["red|reds"], - RHTML: ["Rhtml"], - RST: ["rst"], - Ruby: ["rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile"], - Rust: ["rs"], - SASS: ["sass"], - SCAD: ["scad"], - Scala: ["scala"], - Scheme: ["scm|sm|rkt|oak|scheme"], - SCSS: ["scss"], - SH: ["sh|bash|^.bashrc"], - SJS: ["sjs"], - Slim: ["slim|skim"], - Smarty: ["smarty|tpl"], - snippets: ["snippets"], - Soy_Template:["soy"], - Space: ["space"], - SQL: ["sql"], - SQLServer: ["sqlserver"], - Stylus: ["styl|stylus"], - SVG: ["svg"], - Swift: ["swift"], - Tcl: ["tcl"], - Tex: ["tex"], - Text: ["txt"], - Textile: ["textile"], - Toml: ["toml"], - TSX: ["tsx"], - Twig: ["twig|swig"], - Typescript: ["ts|typescript|str"], - Vala: ["vala"], - VBScript: ["vbs|vb"], - Velocity: ["vm"], - Verilog: ["v|vh|sv|svh"], - VHDL: ["vhd|vhdl"], - Wollok: ["wlk|wpgm|wtest"], - XML: ["xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl|xaml"], - XQuery: ["xq"], - YAML: ["yaml|yml"], - // Add the missing mode "Django" to ext-modelist - Django: ["html"] -}; - -var nameOverrides = { - ObjectiveC: "Objective-C", - CSharp: "C#", - golang: "Go", - C_Cpp: "C and C++", - Csound_Document: "Csound Document", - Csound_Orchestra: "Csound", - Csound_Score: "Csound Score", - coffee: "CoffeeScript", - HTML_Ruby: "HTML (Ruby)", - HTML_Elixir: "HTML (Elixir)", - FTL: "FreeMarker", - PHP_Laravel_blade: "PHP (Blade Template)" -}; -var modesByName = {}; -for (var name in supportedModes) { - var data = supportedModes[name]; - var displayName = (nameOverrides[name] || name).replace(/_/g, " "); - var filename = name.toLowerCase(); - var mode = new Mode(filename, displayName, data[0]); - modesByName[filename] = mode; - modes.push(mode); -} - -module.exports = { - getModeForPath: getModeForPath, - modes: modes, - modesByName: modesByName -}; - -}); diff --git a/lib/ace/ext/options.js b/lib/ace/ext/options.js deleted file mode 100644 index a286a769aef..00000000000 --- a/lib/ace/ext/options.js +++ /dev/null @@ -1,343 +0,0 @@ -define(function(require, exports, module) { -"use strict"; -var overlayPage = require('./menu_tools/overlay_page').overlayPage; - - -var dom = require("../lib/dom"); -var oop = require("../lib/oop"); -var EventEmitter = require("../lib/event_emitter").EventEmitter; -var buildDom = dom.buildDom; - -var modelist = require("./modelist"); -var themelist = require("./themelist"); - -var themes = { Bright: [], Dark: [] }; -themelist.themes.forEach(function(x) { - themes[x.isDark ? "Dark" : "Bright"].push({ caption: x.caption, value: x.theme }); -}); - -var modes = modelist.modes.map(function(x){ - return { caption: x.caption, value: x.mode }; -}); - - -var optionGroups = { - Main: { - Mode: { - path: "mode", - type: "select", - items: modes - }, - Theme: { - path: "theme", - type: "select", - items: themes - }, - "Keybinding": { - type: "buttonBar", - path: "keyboardHandler", - items: [ - { caption : "Ace", value : null }, - { caption : "Vim", value : "ace/keyboard/vim" }, - { caption : "Emacs", value : "ace/keyboard/emacs" } - // { caption : "Sublime", value : "ace/keyboard/sublime" } - ] - }, - "Font Size": { - path: "fontSize", - type: "number", - defaultValue: 12, - defaults: [ - {caption: "12px", value: 12}, - {caption: "24px", value: 24} - ] - }, - "Soft Wrap": { - type: "buttonBar", - path: "wrap", - items: [ - { caption : "Off", value : "off" }, - { caption : "Free", value : "free" }, - { caption : "80", value : "80" }, - { caption : "40", value : "40" } - ] - }, - "Cursor Style": { - path: "cursorStyle", - items: [ - { caption : "Ace", value : "ace" }, - { caption : "Slim", value : "slim" }, - { caption : "Smooth", value : "smooth" }, - { caption : "Smooth And Slim", value : "smooth slim" }, - { caption : "Wide", value : "wide" } - ] - }, - "Folding": { - path: "foldStyle", - items: [ - { caption : "Manual", value : "manual" }, - { caption : "Mark begin", value : "markbegin" }, - { caption : "Mark begin and end", value : "markbeginend" } - ] - }, - "Soft Tabs": [{ - path: "useSoftTabs" - }, { - path: "tabSize", - type: "number", - values: [2, 3, 4, 8, 16] - }], - "Overscroll": { - type: "buttonBar", - path: "scrollPastEnd", - items: [ - { caption : "None", value : 0 }, - { caption : "Half", value : 0.5 }, - { caption : "Full", value : 1 } - ] - } - }, - More: { - "Atomic soft tabs": { - path: "navigateWithinSoftTabs" - }, - "Enable Behaviours": { - path: "behavioursEnabled" - }, - "Full Line Selection": { - type: "checkbox", - values: "text|line", - path: "selectionStyle" - }, - "Highlight Active Line": { - path: "highlightActiveLine" - }, - "Show Invisibles": { - path: "showInvisibles" - }, - "Show Indent Guides": { - path: "displayIndentGuides" - }, - "Persistent Scrollbar": [{ - path: "hScrollBarAlwaysVisible" - }, { - path: "vScrollBarAlwaysVisible" - }], - "Animate scrolling": { - path: "animatedScroll" - }, - "Show Gutter": { - path: "showGutter" - }, - "Show Line Numbers": { - path: "showLineNumbers" - }, - "Relative Line Numbers": { - path: "relativeLineNumbers" - }, - "Fixed Gutter Width": { - path: "fixedWidthGutter" - }, - "Show Print Margin": [{ - path: "showPrintMargin" - }, { - type: "number", - path: "printMarginColumn" - }], - "Indented Soft Wrap": { - path: "indentedSoftWrap" - }, - "Highlight selected word": { - path: "highlightSelectedWord" - }, - "Fade Fold Widgets": { - path: "fadeFoldWidgets" - }, - "Merge Undo Deltas": { - path: "mergeUndoDeltas", - items: [ - { caption : "Always", value : "always" }, - { caption : "Never", value : "false" }, - { caption : "Timed", value : "true" } - ] - }, - "Elastic Tabstops": { - path: "useElasticTabstops" - }, - "Incremental Search": { - path: "useIncrementalSearch" - }, - "Read-only": { - path: "readOnly" - }, - "Copy without selection": { - path: "copyWithEmptySelection" - }, - "Live Autocompletion": { - path: "enableLiveAutocompletion" - } - } -}; - - -var OptionPanel = function(editor, element) { - this.editor = editor; - this.container = element || document.createElement("div"); - this.groups = []; - this.options = {}; -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.add = function(config) { - if (config.Main) - oop.mixin(optionGroups.Main, config.Main); - if (config.More) - oop.mixin(optionGroups.More, config.More); - }; - - this.render = function() { - this.container.innerHTML = ""; - buildDom(["table", {id: "controls"}, - this.renderOptionGroup(optionGroups.Main), - ["tr", null, ["td", {colspan: 2}, - ["table", {id: "more-controls"}, - this.renderOptionGroup(optionGroups.More) - ] - ]] - ], this.container); - }; - - this.renderOptionGroup = function(group) { - return Object.keys(group).map(function(key, i) { - var item = group[key]; - if (!item.position) - item.position = i / 10000; - if (!item.label) - item.label = key; - return item; - }).sort(function(a, b) { - return a.position - b.position; - }).map(function(item) { - return this.renderOption(item.label, item); - }, this); - }; - - this.renderOptionControl = function(key, option) { - var self = this; - if (Array.isArray(option)) { - return option.map(function(x) { - return self.renderOptionControl(key, x); - }); - } - var control; - - var value = self.getOption(option); - - if (option.values && option.type != "checkbox") { - if (typeof option.values == "string") - option.values = option.values.split("|"); - option.items = option.values.map(function(v) { - return { value: v, name: v }; - }); - } - - if (option.type == "buttonBar") { - control = ["div", option.items.map(function(item) { - return ["button", { - value: item.value, - ace_selected_button: value == item.value, - onclick: function() { - self.setOption(option, item.value); - var nodes = this.parentNode.querySelectorAll("[ace_selected_button]"); - for (var i = 0; i < nodes.length; i++) { - nodes[i].removeAttribute("ace_selected_button"); - } - this.setAttribute("ace_selected_button", true); - } - }, item.desc || item.caption || item.name]; - })]; - } else if (option.type == "number") { - control = ["input", {type: "number", value: value || option.defaultValue, style:"width:3em", oninput: function() { - self.setOption(option, parseInt(this.value)); - }}]; - if (option.defaults) { - control = [control, option.defaults.map(function(item) { - return ["button", {onclick: function() { - var input = this.parentNode.firstChild; - input.value = item.value; - input.oninput(); - }}, item.caption]; - })]; - } - } else if (option.items) { - var buildItems = function(items) { - return items.map(function(item) { - return ["option", { value: item.value || item.name }, item.desc || item.caption || item.name]; - }); - }; - - var items = Array.isArray(option.items) - ? buildItems(option.items) - : Object.keys(option.items).map(function(key) { - return ["optgroup", {"label": key}, buildItems(option.items[key])]; - }); - control = ["select", { id: key, value: value, onchange: function() { - self.setOption(option, this.value); - } }, items]; - } else { - if (typeof option.values == "string") - option.values = option.values.split("|"); - if (option.values) value = value == option.values[1]; - control = ["input", { type: "checkbox", id: key, checked: value || null, onchange: function() { - var value = this.checked; - if (option.values) value = option.values[value ? 1 : 0]; - self.setOption(option, value); - }}]; - if (option.type == "checkedNumber") { - control = [control, []]; - } - } - return control; - }; - - this.renderOption = function(key, option) { - if (option.path && !option.onchange && !this.editor.$options[option.path]) - return; - this.options[option.path] = option; - var safeKey = "-" + option.path; - var control = this.renderOptionControl(safeKey, option); - return ["tr", {class: "ace_optionsMenuEntry"}, ["td", - ["label", {for: safeKey}, key] - ], ["td", control]]; - }; - - this.setOption = function(option, value) { - if (typeof option == "string") - option = this.options[option]; - if (value == "false") value = false; - if (value == "true") value = true; - if (value == "null") value = null; - if (value == "undefined") value = undefined; - if (typeof value == "string" && parseFloat(value).toString() == value) - value = parseFloat(value); - if (option.onchange) - option.onchange(value); - else if (option.path) - this.editor.setOption(option.path, value); - this._signal("setOption", {name: option.path, value: value}); - }; - - this.getOption = function(option) { - if (option.getValue) - return option.getValue(); - return this.editor.getOption(option.path); - }; - -}).call(OptionPanel.prototype); - -exports.OptionPanel = OptionPanel; - -}); diff --git a/lib/ace/ext/searchbox.css b/lib/ace/ext/searchbox.css deleted file mode 100644 index 0bdf8cf4bc2..00000000000 --- a/lib/ace/ext/searchbox.css +++ /dev/null @@ -1,162 +0,0 @@ - - -/* ------------------------------------------------------------------------------------------ - * Editor Search Form - * --------------------------------------------------------------------------------------- */ -.ace_search { - background-color: #ddd; - color: #666; - border: 1px solid #cbcbcb; - border-top: 0 none; - overflow: hidden; - margin: 0; - padding: 4px 6px 0 4px; - position: absolute; - top: 0; - z-index: 99; - white-space: normal; -} -.ace_search.left { - border-left: 0 none; - border-radius: 0px 0px 5px 0px; - left: 0; -} -.ace_search.right { - border-radius: 0px 0px 0px 5px; - border-right: 0 none; - right: 0; -} - -.ace_search_form, .ace_replace_form { - margin: 0 20px 4px 0; - overflow: hidden; - line-height: 1.9; -} -.ace_replace_form { - margin-right: 0; -} -.ace_search_form.ace_nomatch { - outline: 1px solid red; -} - -.ace_search_field { - border-radius: 3px 0 0 3px; - background-color: white; - color: black; - border: 1px solid #cbcbcb; - border-right: 0 none; - box-sizing: border-box!important; - outline: 0; - padding: 0; - font-size: inherit; - margin: 0; - line-height: inherit; - padding: 0 6px; - min-width: 17em; - vertical-align: top; -} -.ace_searchbtn { - border: 1px solid #cbcbcb; - line-height: inherit; - display: inline-block; - padding: 0 6px; - background: #fff; - border-right: 0 none; - border-left: 1px solid #dcdcdc; - cursor: pointer; - margin: 0; - position: relative; - box-sizing: content-box!important; - color: #666; -} -.ace_searchbtn:last-child { - border-radius: 0 3px 3px 0; - border-right: 1px solid #cbcbcb; -} -.ace_searchbtn:disabled { - background: none; - cursor: default; -} -.ace_searchbtn:hover { - background-color: #eef1f6; -} -.ace_searchbtn.prev, .ace_searchbtn.next { - padding: 0px 0.7em -} -.ace_searchbtn.prev:after, .ace_searchbtn.next:after { - content: ""; - border: solid 2px #888; - width: 0.5em; - height: 0.5em; - border-width: 2px 0 0 2px; - display:inline-block; - transform: rotate(-45deg); -} -.ace_searchbtn.next:after { - border-width: 0 2px 2px 0 ; -} -.ace_searchbtn_close { - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0; - border-radius: 50%; - border: 0 none; - color: #656565; - cursor: pointer; - font: 16px/16px Arial; - padding: 0; - height: 14px; - width: 14px; - top: 9px; - right: 7px; - position: absolute; -} -.ace_searchbtn_close:hover { - background-color: #656565; - background-position: 50% 100%; - color: white; -} - -.ace_button { - margin-left: 2px; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -o-user-select: none; - -ms-user-select: none; - user-select: none; - overflow: hidden; - opacity: 0.7; - border: 1px solid rgba(100,100,100,0.23); - padding: 1px; - box-sizing: border-box!important; - color: black; -} - -.ace_button:hover { - background-color: #eee; - opacity:1; -} -.ace_button:active { - background-color: #ddd; -} - -.ace_button.checked { - border-color: #3399ff; - opacity:1; -} - -.ace_search_options{ - margin-bottom: 3px; - text-align: right; - -webkit-user-select: none; - -moz-user-select: none; - -o-user-select: none; - -ms-user-select: none; - user-select: none; - clear: both; -} - -.ace_search_counter { - float: left; - font-family: arial; - padding: 0 8px; -} \ No newline at end of file diff --git a/lib/ace/ext/searchbox.js b/lib/ace/ext/searchbox.js deleted file mode 100644 index 854bc23860e..00000000000 --- a/lib/ace/ext/searchbox.js +++ /dev/null @@ -1,399 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var dom = require("../lib/dom"); -var lang = require("../lib/lang"); -var event = require("../lib/event"); -var searchboxCss = require("../requirejs/text!./searchbox.css"); -var HashHandler = require("../keyboard/hash_handler").HashHandler; -var keyUtil = require("../lib/keys"); - -var MAX_COUNT = 999; - -dom.importCssString(searchboxCss, "ace_searchbox"); - -var html = ''.replace(/> +/g, ">"); - -var SearchBox = function(editor, range, showReplaceForm) { - var div = dom.createElement("div"); - div.innerHTML = html; - this.element = div.firstChild; - - this.setSession = this.setSession.bind(this); - - this.$init(); - this.setEditor(editor); -}; - -(function() { - this.setEditor = function(editor) { - editor.searchBox = this; - editor.renderer.scroller.appendChild(this.element); - this.editor = editor; - }; - - this.setSession = function(e) { - this.searchRange = null; - this.$syncOptions(true); - }; - - this.$initElements = function(sb) { - this.searchBox = sb.querySelector(".ace_search_form"); - this.replaceBox = sb.querySelector(".ace_replace_form"); - this.searchOption = sb.querySelector("[action=searchInSelection]"); - this.replaceOption = sb.querySelector("[action=toggleReplace]"); - this.regExpOption = sb.querySelector("[action=toggleRegexpMode]"); - this.caseSensitiveOption = sb.querySelector("[action=toggleCaseSensitive]"); - this.wholeWordOption = sb.querySelector("[action=toggleWholeWords]"); - this.searchInput = this.searchBox.querySelector(".ace_search_field"); - this.replaceInput = this.replaceBox.querySelector(".ace_search_field"); - this.searchCounter = sb.querySelector(".ace_search_counter"); - }; - - this.$init = function() { - var sb = this.element; - - this.$initElements(sb); - - var _this = this; - event.addListener(sb, "mousedown", function(e) { - setTimeout(function(){ - _this.activeInput.focus(); - }, 0); - event.stopPropagation(e); - }); - event.addListener(sb, "click", function(e) { - var t = e.target || e.srcElement; - var action = t.getAttribute("action"); - if (action && _this[action]) - _this[action](); - else if (_this.$searchBarKb.commands[action]) - _this.$searchBarKb.commands[action].exec(_this); - event.stopPropagation(e); - }); - - event.addCommandKeyListener(sb, function(e, hashId, keyCode) { - var keyString = keyUtil.keyCodeToString(keyCode); - var command = _this.$searchBarKb.findKeyCommand(hashId, keyString); - if (command && command.exec) { - command.exec(_this); - event.stopEvent(e); - } - }); - - this.$onChange = lang.delayedCall(function() { - _this.find(false, false); - }); - - event.addListener(this.searchInput, "input", function() { - _this.$onChange.schedule(20); - }); - event.addListener(this.searchInput, "focus", function() { - _this.activeInput = _this.searchInput; - _this.searchInput.value && _this.highlight(); - }); - event.addListener(this.replaceInput, "focus", function() { - _this.activeInput = _this.replaceInput; - _this.searchInput.value && _this.highlight(); - }); - }; - - //keybinding outside of the searchbox - this.$closeSearchBarKb = new HashHandler([{ - bindKey: "Esc", - name: "closeSearchBar", - exec: function(editor) { - editor.searchBox.hide(); - } - }]); - - //keybinding outside of the searchbox - this.$searchBarKb = new HashHandler(); - this.$searchBarKb.bindKeys({ - "Ctrl-f|Command-f": function(sb) { - var isReplace = sb.isReplace = !sb.isReplace; - sb.replaceBox.style.display = isReplace ? "" : "none"; - sb.replaceOption.checked = false; - sb.$syncOptions(); - sb.searchInput.focus(); - }, - "Ctrl-H|Command-Option-F": function(sb) { - sb.replaceOption.checked = true; - sb.$syncOptions(); - sb.replaceInput.focus(); - }, - "Ctrl-G|Command-G": function(sb) { - sb.findNext(); - }, - "Ctrl-Shift-G|Command-Shift-G": function(sb) { - sb.findPrev(); - }, - "esc": function(sb) { - setTimeout(function() { sb.hide();}); - }, - "Return": function(sb) { - if (sb.activeInput == sb.replaceInput) - sb.replace(); - sb.findNext(); - }, - "Shift-Return": function(sb) { - if (sb.activeInput == sb.replaceInput) - sb.replace(); - sb.findPrev(); - }, - "Alt-Return": function(sb) { - if (sb.activeInput == sb.replaceInput) - sb.replaceAll(); - sb.findAll(); - }, - "Tab": function(sb) { - (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus(); - } - }); - - this.$searchBarKb.addCommands([{ - name: "toggleRegexpMode", - bindKey: {win: "Alt-R|Alt-/", mac: "Ctrl-Alt-R|Ctrl-Alt-/"}, - exec: function(sb) { - sb.regExpOption.checked = !sb.regExpOption.checked; - sb.$syncOptions(); - } - }, { - name: "toggleCaseSensitive", - bindKey: {win: "Alt-C|Alt-I", mac: "Ctrl-Alt-R|Ctrl-Alt-I"}, - exec: function(sb) { - sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked; - sb.$syncOptions(); - } - }, { - name: "toggleWholeWords", - bindKey: {win: "Alt-B|Alt-W", mac: "Ctrl-Alt-B|Ctrl-Alt-W"}, - exec: function(sb) { - sb.wholeWordOption.checked = !sb.wholeWordOption.checked; - sb.$syncOptions(); - } - }, { - name: "toggleReplace", - exec: function(sb) { - sb.replaceOption.checked = !sb.replaceOption.checked; - sb.$syncOptions(); - } - }, { - name: "searchInSelection", - exec: function(sb) { - sb.searchOption.checked = !sb.searchRange; - sb.setSearchRange(sb.searchOption.checked && sb.editor.getSelectionRange()); - sb.$syncOptions(); - } - }]); - - this.setSearchRange = function(range) { - this.searchRange = range; - if (range) { - this.searchRangeMarker = this.editor.session.addMarker(range, "ace_active-line"); - } else if (this.searchRangeMarker) { - this.editor.session.removeMarker(this.searchRangeMarker); - this.searchRangeMarker = null; - } - }; - - this.$syncOptions = function(preventScroll) { - dom.setCssClass(this.replaceOption, "checked", this.searchRange); - dom.setCssClass(this.searchOption, "checked", this.searchOption.checked); - this.replaceOption.textContent = this.replaceOption.checked ? "-" : "+"; - dom.setCssClass(this.regExpOption, "checked", this.regExpOption.checked); - dom.setCssClass(this.wholeWordOption, "checked", this.wholeWordOption.checked); - dom.setCssClass(this.caseSensitiveOption, "checked", this.caseSensitiveOption.checked); - this.replaceBox.style.display = this.replaceOption.checked ? "" : "none"; - this.find(false, false, preventScroll); - }; - - this.highlight = function(re) { - this.editor.session.highlight(re || this.editor.$search.$options.re); - this.editor.renderer.updateBackMarkers(); - }; - this.find = function(skipCurrent, backwards, preventScroll) { - var range = this.editor.find(this.searchInput.value, { - skipCurrent: skipCurrent, - backwards: backwards, - wrap: true, - regExp: this.regExpOption.checked, - caseSensitive: this.caseSensitiveOption.checked, - wholeWord: this.wholeWordOption.checked, - preventScroll: preventScroll, - range: this.searchRange - }); - var noMatch = !range && this.searchInput.value; - dom.setCssClass(this.searchBox, "ace_nomatch", noMatch); - this.editor._emit("findSearchBox", { match: !noMatch }); - this.highlight(); - this.updateCounter(); - }; - this.updateCounter = function() { - var editor = this.editor; - var regex = editor.$search.$options.re; - var all = 0; - var before = 0; - if (regex) { - var value = this.searchRange - ? editor.session.getTextRange(this.searchRange) - : editor.getValue(); - - var offset = editor.session.doc.positionToIndex(editor.selection.anchor); - if (this.searchRange) - offset -= editor.session.doc.positionToIndex(this.searchRange.start); - - var last = regex.lastIndex = 0; - var m; - while ((m = regex.exec(value))) { - all++; - last = m.index; - if (last <= offset) - before++; - if (all > MAX_COUNT) - break; - if (!m[0]) { - regex.lastIndex = last += 1; - if (last >= value.length) - break; - } - } - } - this.searchCounter.textContent = before + " of " + (all > MAX_COUNT ? MAX_COUNT + "+" : all); - }; - this.findNext = function() { - this.find(true, false); - }; - this.findPrev = function() { - this.find(true, true); - }; - this.findAll = function(){ - var range = this.editor.findAll(this.searchInput.value, { - regExp: this.regExpOption.checked, - caseSensitive: this.caseSensitiveOption.checked, - wholeWord: this.wholeWordOption.checked - }); - var noMatch = !range && this.searchInput.value; - dom.setCssClass(this.searchBox, "ace_nomatch", noMatch); - this.editor._emit("findSearchBox", { match: !noMatch }); - this.highlight(); - this.hide(); - }; - this.replace = function() { - if (!this.editor.getReadOnly()) - this.editor.replace(this.replaceInput.value); - }; - this.replaceAndFindNext = function() { - if (!this.editor.getReadOnly()) { - this.editor.replace(this.replaceInput.value); - this.findNext(); - } - }; - this.replaceAll = function() { - if (!this.editor.getReadOnly()) - this.editor.replaceAll(this.replaceInput.value); - }; - - this.hide = function() { - this.active = false; - this.setSearchRange(null); - this.editor.off("changeSession", this.setSession); - - this.element.style.display = "none"; - this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb); - this.editor.focus(); - }; - this.show = function(value, isReplace) { - this.active = true; - this.editor.on("changeSession", this.setSession); - this.element.style.display = ""; - this.replaceOption.checked = isReplace; - - if (value) - this.searchInput.value = value; - - this.searchInput.focus(); - this.searchInput.select(); - - this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb); - - this.$syncOptions(true); - }; - - this.isFocused = function() { - var el = document.activeElement; - return el == this.searchInput || el == this.replaceInput; - }; -}).call(SearchBox.prototype); - -exports.SearchBox = SearchBox; - -exports.Search = function(editor, isReplace) { - var sb = editor.searchBox || new SearchBox(editor); - sb.show(editor.session.getTextRange(), isReplace); -}; - -}); - - -/* ------------------------------------------------------------------------------------------ - * TODO - * --------------------------------------------------------------------------------------- */ -/* -- move search form to the left if it masks current word -- include all options that search has. ex: regex -- searchbox.searchbox is not that pretty. We should have just searchbox -- disable prev button if it makes sense -*/ diff --git a/lib/ace/ext/settings_menu.js b/lib/ace/ext/settings_menu.js deleted file mode 100644 index 7ead5f9eeca..00000000000 --- a/lib/ace/ext/settings_menu.js +++ /dev/null @@ -1,80 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl - * All rights reserved. - * - * Contributed to Ajax.org under the BSD license. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ -/*global define, require */ - -/** - * Show Settings Menu - * @fileOverview Show Settings Menu
      - * Displays an interactive settings menu mostly generated on the fly based on - * the current state of the editor. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - */ - -define(function(require, exports, module) { -"use strict"; -var OptionPanel = require("ace/ext/options").OptionPanel; -var overlayPage = require('./menu_tools/overlay_page').overlayPage; -/** - * This displays the settings menu if it is not already being shown. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - * @param {ace.Editor} editor An instance of the ace editor. - */ -function showSettingsMenu(editor) { - // show if the menu isn't open already. - if (!document.getElementById('ace_settingsmenu')) { - var options = new OptionPanel(editor); - options.render(); - options.container.id = "ace_settingsmenu"; - overlayPage(editor, options.container, '0', '0', '0'); - options.container.querySelector("select,input,button,checkbox").focus(); - } -} - -/** - * Initializes the settings menu extension. It adds the showSettingsMenu - * method to the given editor object and adds the showSettingsMenu command - * to the editor with appropriate keyboard shortcuts. - * @param {ace.Editor} editor An instance of the Editor. - */ -module.exports.init = function(editor) { - var Editor = require("ace/editor").Editor; - Editor.prototype.showSettingsMenu = function() { - showSettingsMenu(this); - }; -}; -}); \ No newline at end of file diff --git a/lib/ace/ext/spellcheck.js b/lib/ace/ext/spellcheck.js deleted file mode 100644 index 713b9057fdb..00000000000 --- a/lib/ace/ext/spellcheck.js +++ /dev/null @@ -1,69 +0,0 @@ -define(function(require, exports, module) { -"use strict"; -var event = require("../lib/event"); - -exports.contextMenuHandler = function(e){ - var host = e.target; - var text = host.textInput.getElement(); - if (!host.selection.isEmpty()) - return; - var c = host.getCursorPosition(); - var r = host.session.getWordRange(c.row, c.column); - var w = host.session.getTextRange(r); - - host.session.tokenRe.lastIndex = 0; - if (!host.session.tokenRe.test(w)) - return; - var PLACEHOLDER = "\x01\x01"; - var value = w + " " + PLACEHOLDER; - text.value = value; - text.setSelectionRange(w.length, w.length + 1); - text.setSelectionRange(0, 0); - text.setSelectionRange(0, w.length); - - var afterKeydown = false; - event.addListener(text, "keydown", function onKeydown() { - event.removeListener(text, "keydown", onKeydown); - afterKeydown = true; - }); - - host.textInput.setInputHandler(function(newVal) { - console.log(newVal , value, text.selectionStart, text.selectionEnd); - if (newVal == value) - return ''; - if (newVal.lastIndexOf(value, 0) === 0) - return newVal.slice(value.length); - if (newVal.substr(text.selectionEnd) == value) - return newVal.slice(0, -value.length); - if (newVal.slice(-2) == PLACEHOLDER) { - var val = newVal.slice(0, -2); - if (val.slice(-1) == " ") { - if (afterKeydown) - return val.substring(0, text.selectionEnd); - val = val.slice(0, -1); - host.session.replace(r, val); - return ""; - } - } - - return newVal; - }); -}; -// todo support highlighting with typo.js -var Editor = require("../editor").Editor; -require("../config").defineOptions(Editor.prototype, "editor", { - spellcheck: { - set: function(val) { - var text = this.textInput.getElement(); - text.spellcheck = !!val; - if (!val) - this.removeListener("nativecontextmenu", exports.contextMenuHandler); - else - this.on("nativecontextmenu", exports.contextMenuHandler); - }, - value: true - } -}); - -}); - diff --git a/lib/ace/ext/split.js b/lib/ace/ext/split.js deleted file mode 100644 index 8316562fd6c..00000000000 --- a/lib/ace/ext/split.js +++ /dev/null @@ -1,40 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -/** - * this is experimental, and subject to change, use at your own risk! - */ -module.exports = require("../split"); - -}); - diff --git a/lib/ace/ext/static.css b/lib/ace/ext/static.css deleted file mode 100644 index 51986c3f2f3..00000000000 --- a/lib/ace/ext/static.css +++ /dev/null @@ -1,38 +0,0 @@ -.ace_static_highlight { - font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'Droid Sans Mono', monospace; - font-size: 12px; - white-space: pre-wrap -} - -.ace_static_highlight .ace_gutter { - width: 2em; - text-align: right; - padding: 0 3px 0 0; - margin-right: 3px; -} - -.ace_static_highlight.ace_show_gutter .ace_line { - padding-left: 2.6em; -} - -.ace_static_highlight .ace_line { position: relative; } - -.ace_static_highlight .ace_gutter-cell { - -moz-user-select: -moz-none; - -khtml-user-select: none; - -webkit-user-select: none; - user-select: none; - top: 0; - bottom: 0; - left: 0; - position: absolute; -} - - -.ace_static_highlight .ace_gutter-cell:before { - content: counter(ace_line, decimal); - counter-increment: ace_line; -} -.ace_static_highlight { - counter-reset: ace_line; -} diff --git a/lib/ace/ext/static_highlight.js b/lib/ace/ext/static_highlight.js deleted file mode 100644 index e45e83cca80..00000000000 --- a/lib/ace/ext/static_highlight.js +++ /dev/null @@ -1,267 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var EditSession = require("../edit_session").EditSession; -var TextLayer = require("../layer/text").Text; -var baseStyles = require("../requirejs/text!./static.css"); -var config = require("../config"); -var dom = require("../lib/dom"); - -var simpleDom = { - createTextNode: function(textContent) { - return textContent; - }, - createElement: function(type) { - var element = { - type: type, - style: {}, - childNodes: [], - appendChild: function(child) { - element.childNodes.push(child); - }, - toString: function() { - var internal = { - type: 1, - style: 1, - className: 1, - textContent: 1, - childNodes: 1, - appendChild: 1, - toString: 1 - }; - var stringBuilder = []; - - if (element.type != "fragment") { - stringBuilder.push("<", element.type); - if (element.className) - stringBuilder.push(" class='", element.className, "'"); - var styleStr = []; - for (var key in element.style) { - styleStr.push(key, ":", element.style[key]); - } - if (styleStr.length) - stringBuilder.push(" style='", styleStr.join(""), "'"); - for (var key in element) { - if (!internal[key]) { - stringBuilder.push(" ", key, "='", element[key], "'"); - } - } - stringBuilder.push(">"); - } - - if (element.textContent) { - stringBuilder.push(element.textContent); - } else { - for (var i=0; i"); - } - - return stringBuilder.join(""); - } - }; - return element; - }, - createFragment: function() { - return this.createElement("fragment"); - } -}; - -var SimpleTextLayer = function() { - this.config = {}; - this.dom = simpleDom; -}; -SimpleTextLayer.prototype = TextLayer.prototype; - -var highlight = function(el, opts, callback) { - var m = el.className.match(/lang-(\w+)/); - var mode = opts.mode || m && ("ace/mode/" + m[1]); - if (!mode) - return false; - var theme = opts.theme || "ace/theme/textmate"; - - var data = ""; - var nodes = []; - - if (el.firstElementChild) { - var textLen = 0; - for (var i = 0; i < el.childNodes.length; i++) { - var ch = el.childNodes[i]; - if (ch.nodeType == 3) { - textLen += ch.data.length; - data += ch.data; - } else { - nodes.push(textLen, ch); - } - } - } else { - data = el.textContent; - if (opts.trim) - data = data.trim(); - } - - highlight.render(data, mode, theme, opts.firstLineNumber, !opts.showGutter, function (highlighted) { - dom.importCssString(highlighted.css, "ace_highlight"); - el.innerHTML = highlighted.html; - var container = el.firstChild.firstChild; - for (var i = 0; i < nodes.length; i += 2) { - var pos = highlighted.session.doc.indexToPosition(nodes[i]); - var node = nodes[i + 1]; - var lineEl = container.children[pos.row]; - lineEl && lineEl.appendChild(node); - } - callback && callback(); - }); -}; - -/** - * Transforms a given input code snippet into HTML using the given mode - * - * @param {string} input Code snippet - * @param {string|mode} mode String specifying the mode to load such as - * `ace/mode/javascript` or, a mode loaded from `/ace/mode` - * (use 'ServerSideHiglighter.getMode'). - * @param {string|theme} theme String specifying the theme to load such as - * `ace/theme/twilight` or, a theme loaded from `/ace/theme`. - * @param {number} lineStart A number indicating the first line number. Defaults - * to 1. - * @param {boolean} disableGutter Specifies whether or not to disable the gutter. - * `true` disables the gutter, `false` enables the gutter. Defaults to `false`. - * @param {function} callback When specifying the mode or theme as a string, - * this method has no return value and you must specify a callback function. The - * callback will receive the rendered object containing the properties `html` - * and `css`. - * @returns {object} An object containing the properties `html` and `css`. - */ -highlight.render = function(input, mode, theme, lineStart, disableGutter, callback) { - var waiting = 1; - var modeCache = EditSession.prototype.$modes; - - // if either the theme or the mode were specified as objects - // then we need to lazily load them. - if (typeof theme == "string") { - waiting++; - config.loadModule(['theme', theme], function(m) { - theme = m; - --waiting || done(); - }); - } - // allow setting mode options e.h {path: "ace/mode/php", inline:true} - var modeOptions; - if (mode && typeof mode === "object" && !mode.getTokenizer) { - modeOptions = mode; - mode = modeOptions.path; - } - if (typeof mode == "string") { - waiting++; - config.loadModule(['mode', mode], function(m) { - if (!modeCache[mode] || modeOptions) - modeCache[mode] = new m.Mode(modeOptions); - mode = modeCache[mode]; - --waiting || done(); - }); - } - - // loads or passes the specified mode module then calls renderer - function done() { - var result = highlight.renderSync(input, mode, theme, lineStart, disableGutter); - return callback ? callback(result) : result; - } - return --waiting || done(); -}; - -/** - * Transforms a given input code snippet into HTML using the given mode - * @param {string} input Code snippet - * @param {mode} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode') - * @param {string} r Code snippet - * @returns {object} An object containing: html, css - */ -highlight.renderSync = function(input, mode, theme, lineStart, disableGutter) { - lineStart = parseInt(lineStart || 1, 10); - - var session = new EditSession(""); - session.setUseWorker(false); - session.setMode(mode); - - var textLayer = new SimpleTextLayer(); - textLayer.setSession(session); - - session.setValue(input); - var length = session.getLength(); - - var outerEl = simpleDom.createElement("div"); - outerEl.className = theme.cssClass; - - var innerEl = simpleDom.createElement("div"); - innerEl.className = "ace_static_highlight" + (disableGutter ? "" : " ace_show_gutter"); - innerEl.style["counter-reset"] = "ace_line " + (lineStart - 1); - outerEl.appendChild(innerEl); - - for (var ix = 0; ix < length; ix++) { - var lineEl = simpleDom.createElement("div"); - lineEl.className = "ace_line"; - - if (!disableGutter) { - var gutterEl = simpleDom.createElement("span"); - gutterEl.className ="ace_gutter ace_gutter-cell"; - gutterEl.unselectable ="on"; - gutterEl.textContent = ""; /*(ix + lineStart) + */ - lineEl.appendChild(gutterEl); - } - textLayer.$renderLine(lineEl, ix, false); - innerEl.appendChild(lineEl); - } - - //console.log(JSON.stringify(outerEl, null, 2)); - //console.log(outerEl.toString()); - textLayer.destroy(); - - return { - css: baseStyles + theme.cssText, - html: outerEl.toString(), - session: session - }; -}; - -module.exports = highlight; -module.exports.highlight = highlight; -}); diff --git a/lib/ace/ext/static_highlight_test.js b/lib/ace/ext/static_highlight_test.js deleted file mode 100644 index bbefef41d04..00000000000 --- a/lib/ace/ext/static_highlight_test.js +++ /dev/null @@ -1,102 +0,0 @@ -if (typeof process !== "undefined") { - require("amd-loader"); -} - -define(function(require, exports, module) { -"use strict"; - -var assert = require("assert"); -var highlighter = require("./static_highlight"); -var JavaScriptMode = require("../mode/javascript").Mode; -var TextMode = require("../mode/text").Mode; - -// Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite -module.exports = { - timeout: 10000, - - "test loading in node": function(next) { - if (typeof process != "undefined") - assert.equal(typeof window, "undefined"); - require("../ace"); - next(); - }, - - "test simple snippet": function(next) { - var theme = require("../theme/tomorrow"); - var snippet = [ - "/** this is a function", - "*", - "*/", - "function hello (a, b, c) {", - " console.log(a * b + c + 'sup$');", - "}" - ].join("\n"); - var mode = new JavaScriptMode(); - - var result = highlighter.render(snippet, mode, theme); - assert.equal(result.html, "
      " - + "
      /** this is a function
      " - + "
      *
      " - + "
      */
      " - + "
      function hello (a, b, c) {
      " - + "
      console.log(a * b + c + 'sup$');
      " - + "
      }
      " - + "
      "); - assert.ok(!!result.css); - next(); - }, - - "test css from theme is used": function(next) { - var theme = require("../theme/tomorrow"); - var snippet = [ - "/** this is a function", - "*", - "*/", - "function hello (a, b, c) {", - " console.log(a * b + c + 'sup?');", - "}" - ].join("\n"); - var mode = new JavaScriptMode(); - - var result = highlighter.render(snippet, mode, theme); - - assert.ok(result.css.indexOf(theme.cssText) !== -1); - - next(); - }, - - "test theme classname should be in output html": function(next) { - var theme = require("../theme/tomorrow"); - var snippet = [ - "/** this is a function", - "*", - "*/", - "function hello (a, b, c) {", - " console.log(a * b + c + 'sup?');", - "}" - ].join("\n"); - var mode = new JavaScriptMode(); - - var result = highlighter.render(snippet, mode, theme); - assert.equal(!!result.html.match(/
      /), true); - - next(); - }, - - "test js string replace specials": function(next) { - var theme = require("../theme/tomorrow"); - var snippet = "$'$1$2$$$&"; - var mode = new TextMode(); - - var result = highlighter.render(snippet, mode, theme); - assert.ok(result.html.indexOf(snippet) != -1); - - next(); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/ext/statusbar.js b/lib/ace/ext/statusbar.js deleted file mode 100644 index 20e1a099181..00000000000 --- a/lib/ace/ext/statusbar.js +++ /dev/null @@ -1,50 +0,0 @@ -define(function(require, exports, module) { -"use strict"; -/** simple statusbar **/ -var dom = require("ace/lib/dom"); -var lang = require("ace/lib/lang"); - -var StatusBar = function(editor, parentNode) { - this.element = dom.createElement("div"); - this.element.className = "ace_status-indicator"; - this.element.style.cssText = "display: inline-block;"; - parentNode.appendChild(this.element); - - var statusUpdate = lang.delayedCall(function(){ - this.updateStatus(editor); - }.bind(this)).schedule.bind(null, 100); - - editor.on("changeStatus", statusUpdate); - editor.on("changeSelection", statusUpdate); - editor.on("keyboardActivity", statusUpdate); -}; - -(function(){ - this.updateStatus = function(editor) { - var status = []; - function add(str, separator) { - str && status.push(str, separator || "|"); - } - - add(editor.keyBinding.getStatusText(editor)); - if (editor.commands.recording) - add("REC"); - - var sel = editor.selection; - var c = sel.lead; - - if (!sel.isEmpty()) { - var r = editor.getSelectionRange(); - add("(" + (r.end.row - r.start.row) + ":" +(r.end.column - r.start.column) + ")", " "); - } - add(c.row + ":" + c.column, " "); - if (sel.rangeCount) - add("[" + sel.rangeCount + "]", " "); - status.pop(); - this.element.textContent = status.join(""); - }; -}).call(StatusBar.prototype); - -exports.StatusBar = StatusBar; - -}); \ No newline at end of file diff --git a/lib/ace/ext/textarea.js b/lib/ace/ext/textarea.js deleted file mode 100644 index f74d5be5507..00000000000 --- a/lib/ace/ext/textarea.js +++ /dev/null @@ -1,521 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var event = require("../lib/event"); -var UA = require("../lib/useragent"); -var net = require("../lib/net"); -var ace = require("../ace"); - -require("../theme/textmate"); - -module.exports = exports = ace; - -/* - * Returns the CSS property of element. - * 1) If the CSS property is on the style object of the element, use it, OR - * 2) Compute the CSS property - * - * If the property can't get computed, is 'auto' or 'intrinsic', the former - * calculated property is used (this can happen in cases where the textarea - * is hidden and has no dimension styles). - */ -var getCSSProperty = function(element, container, property) { - var ret = element.style[property]; - - if (!ret) { - if (window.getComputedStyle) { - ret = window.getComputedStyle(element, '').getPropertyValue(property); - } else { - ret = element.currentStyle[property]; - } - } - - if (!ret || ret == 'auto' || ret == 'intrinsic') { - ret = container.style[property]; - } - return ret; -}; - -function applyStyles(elm, styles) { - for (var style in styles) { - elm.style[style] = styles[style]; - } -} - -function setupContainer(element, getValue) { - if (element.type != 'textarea') { - throw new Error("Textarea required!"); - } - - var parentNode = element.parentNode; - - // This will hold the editor. - var container = document.createElement('div'); - - // To put Ace in the place of the textarea, we have to copy a few of the - // textarea's style attributes to the div container. - // - // The problem is that the properties have to get computed (they might be - // defined by a CSS file on the page - you can't access such rules that - // apply to an element via elm.style). Computed properties are converted to - // pixels although the dimension might be given as percentage. When the - // window resizes, the dimensions defined by percentages changes, so the - // properties have to get recomputed to get the new/true pixels. - var resizeEvent = function() { - var style = 'position:relative;'; - [ - 'margin-top', 'margin-left', 'margin-right', 'margin-bottom' - ].forEach(function(item) { - style += item + ':' + - getCSSProperty(element, container, item) + ';'; - }); - - // Calculating the width/height of the textarea is somewhat tricky. To - // do it right, you have to include the paddings to the sides as well - // (eg. width = width + padding-left, -right). This works well, as - // long as the width of the element is not set or given in pixels. In - // this case and after the textarea is hidden, getCSSProperty(element, - // container, 'width') will still return pixel value. If the element - // has realtiv dimensions (e.g. width='95') - // getCSSProperty(...) will return pixel values only as long as the - // textarea is visible. After it is hidden getCSSProperty will return - // the relative dimensions as they are set on the element (in the case - // of width, 95). - // Making the sum of pixel vaules (e.g. padding) and realtive values - // (e.g. ) is not possible. As such the padding styles are - // ignored. - - // The complete width is the width of the textarea + the padding - // to the left and right. - var width = getCSSProperty(element, container, 'width') || (element.clientWidth + "px"); - var height = getCSSProperty(element, container, 'height') || (element.clientHeight + "px"); - style += 'height:' + height + ';width:' + width + ';'; - - // Set the display property to 'inline-block'. - style += 'display:inline-block;'; - container.setAttribute('style', style); - }; - event.addListener(window, 'resize', resizeEvent); - - // Call the resizeEvent once, so that the size of the container is - // calculated. - resizeEvent(); - - // Insert the div container after the element. - parentNode.insertBefore(container, element.nextSibling); - - // Override the forms onsubmit function. Set the innerHTML and value - // of the textarea before submitting. - while (parentNode !== document) { - if (parentNode.tagName.toUpperCase() === 'FORM') { - var oldSumit = parentNode.onsubmit; - // Override the onsubmit function of the form. - parentNode.onsubmit = function(evt) { - element.value = getValue(); - // If there is a onsubmit function already, then call - // it with the current context and pass the event. - if (oldSumit) { - oldSumit.call(this, evt); - } - }; - break; - } - parentNode = parentNode.parentNode; - } - return container; -} - -exports.transformTextarea = function(element, options) { - var isFocused = element.autofocus || document.activeElement == element; - var session; - var container = setupContainer(element, function() { - return session.getValue(); - }); - - // Hide the element. - element.style.display = 'none'; - container.style.background = 'white'; - - // - var editorDiv = document.createElement("div"); - applyStyles(editorDiv, { - top: "0px", - left: "0px", - right: "0px", - bottom: "0px", - border: "1px solid gray", - position: "absolute" - }); - container.appendChild(editorDiv); - - var settingOpener = document.createElement("div"); - applyStyles(settingOpener, { - position: "absolute", - right: "0px", - bottom: "0px", - cursor: "nw-resize", - border: "solid 9px", - borderColor: "lightblue gray gray #ceade6", - zIndex: 101 - }); - - var settingDiv = document.createElement("div"); - var settingDivStyles = { - top: "0px", - left: "20%", - right: "0px", - bottom: "0px", - position: "absolute", - padding: "5px", - zIndex: 100, - color: "white", - display: "none", - overflow: "auto", - fontSize: "14px", - boxShadow: "-5px 2px 3px gray" - }; - if (!UA.isOldIE) { - settingDivStyles.backgroundColor = "rgba(0, 0, 0, 0.6)"; - } else { - settingDivStyles.backgroundColor = "#333"; - } - - applyStyles(settingDiv, settingDivStyles); - container.appendChild(settingDiv); - - options = options || exports.defaultOptions; - // Power up ace on the textarea: - var editor = ace.edit(editorDiv); - session = editor.getSession(); - - session.setValue(element.value || element.innerHTML); - if (isFocused) - editor.focus(); - - // Add the settingPanel opener to the editor's div. - container.appendChild(settingOpener); - - // Create the API. - setupApi(editor, editorDiv, settingDiv, ace, options); - - // Create the setting's panel. - setupSettingPanel(settingDiv, settingOpener, editor); - - var state = ""; - event.addListener(settingOpener, "mousemove", function(e) { - var rect = this.getBoundingClientRect(); - var x = e.clientX - rect.left, y = e.clientY - rect.top; - if (x + y < (rect.width + rect.height)/2) { - this.style.cursor = "pointer"; - state = "toggle"; - } else { - state = "resize"; - this.style.cursor = "nw-resize"; - } - }); - - event.addListener(settingOpener, "mousedown", function(e) { - e.preventDefault(); - if (state == "toggle") { - editor.setDisplaySettings(); - return; - } - container.style.zIndex = 100000; - var rect = container.getBoundingClientRect(); - var startX = rect.width + rect.left - e.clientX; - var startY = rect.height + rect.top - e.clientY; - event.capture(settingOpener, function(e) { - container.style.width = e.clientX - rect.left + startX + "px"; - container.style.height = e.clientY - rect.top + startY + "px"; - editor.resize(); - }, function() {}); - }); - - return editor; -}; - -function load(url, module, callback) { - net.loadScript(url, function() { - require([module], callback); - }); -} - -function setupApi(editor, editorDiv, settingDiv, ace, options) { - var session = editor.getSession(); - var renderer = editor.renderer; - - function toBool(value) { - return value === "true" || value == true; - } - - editor.setDisplaySettings = function(display) { - if (display == null) - display = settingDiv.style.display == "none"; - if (display) { - settingDiv.style.display = "block"; - settingDiv.hideButton.focus(); - editor.on("focus", function onFocus() { - editor.removeListener("focus", onFocus); - settingDiv.style.display = "none"; - }); - } else { - editor.focus(); - } - }; - - editor.$setOption = editor.setOption; - editor.$getOption = editor.getOption; - editor.setOption = function(key, value) { - switch (key) { - case "mode": - editor.$setOption("mode", "ace/mode/" + value); - break; - case "theme": - editor.$setOption("theme", "ace/theme/" + value); - break; - case "keybindings": - switch (value) { - case "vim": - editor.setKeyboardHandler("ace/keyboard/vim"); - break; - case "emacs": - editor.setKeyboardHandler("ace/keyboard/emacs"); - break; - default: - editor.setKeyboardHandler(null); - } - break; - - case "wrap": - case "fontSize": - editor.$setOption(key, value); - break; - - default: - editor.$setOption(key, toBool(value)); - } - }; - - editor.getOption = function(key) { - switch (key) { - case "mode": - return editor.$getOption("mode").substr("ace/mode/".length); - break; - - case "theme": - return editor.$getOption("theme").substr("ace/theme/".length); - break; - - case "keybindings": - var value = editor.getKeyboardHandler(); - switch (value && value.$id) { - case "ace/keyboard/vim": - return "vim"; - case "ace/keyboard/emacs": - return "emacs"; - default: - return "ace"; - } - break; - - default: - return editor.$getOption(key); - } - }; - - editor.setOptions(options); - return editor; -} - -function setupSettingPanel(settingDiv, settingOpener, editor) { - var BOOL = null; - - var desc = { - mode: "Mode:", - wrap: "Soft Wrap:", - theme: "Theme:", - fontSize: "Font Size:", - showGutter: "Display Gutter:", - keybindings: "Keyboard", - showPrintMargin: "Show Print Margin:", - useSoftTabs: "Use Soft Tabs:", - showInvisibles: "Show Invisibles" - }; - - var optionValues = { - mode: { - text: "Plain", - javascript: "JavaScript", - xml: "XML", - html: "HTML", - css: "CSS", - scss: "SCSS", - python: "Python", - php: "PHP", - java: "Java", - ruby: "Ruby", - c_cpp: "C/C++", - coffee: "CoffeeScript", - json: "json", - perl: "Perl", - clojure: "Clojure", - ocaml: "OCaml", - csharp: "C#", - haxe: "haXe", - svg: "SVG", - textile: "Textile", - groovy: "Groovy", - liquid: "Liquid", - Scala: "Scala" - }, - theme: { - clouds: "Clouds", - clouds_midnight: "Clouds Midnight", - cobalt: "Cobalt", - crimson_editor: "Crimson Editor", - dawn: "Dawn", - gob: "Green on Black", - eclipse: "Eclipse", - idle_fingers: "Idle Fingers", - kr_theme: "Kr Theme", - merbivore: "Merbivore", - merbivore_soft: "Merbivore Soft", - mono_industrial: "Mono Industrial", - monokai: "Monokai", - pastel_on_dark: "Pastel On Dark", - solarized_dark: "Solarized Dark", - solarized_light: "Solarized Light", - textmate: "Textmate", - twilight: "Twilight", - vibrant_ink: "Vibrant Ink" - }, - showGutter: BOOL, - fontSize: { - "10px": "10px", - "11px": "11px", - "12px": "12px", - "14px": "14px", - "16px": "16px" - }, - wrap: { - off: "Off", - 40: "40", - 80: "80", - free: "Free" - }, - keybindings: { - ace: "ace", - vim: "vim", - emacs: "emacs" - }, - showPrintMargin: BOOL, - useSoftTabs: BOOL, - showInvisibles: BOOL - }; - - var table = []; - table.push(""); - - function renderOption(builder, option, obj, cValue) { - if (!obj) { - builder.push( - "" - ); - return; - } - builder.push(""); - } - - for (var option in exports.defaultOptions) { - table.push(""); - table.push(""); - } - table.push("
      SettingValue
      ", desc[option], ""); - renderOption(table, option, optionValues[option], editor.getOption(option)); - table.push("
      "); - settingDiv.innerHTML = table.join(""); - - var onChange = function(e) { - var select = e.currentTarget; - editor.setOption(select.title, select.value); - }; - var onClick = function(e) { - var cb = e.currentTarget; - editor.setOption(cb.title, cb.checked); - }; - var selects = settingDiv.getElementsByTagName("select"); - for (var i = 0; i < selects.length; i++) - selects[i].onchange = onChange; - var cbs = settingDiv.getElementsByTagName("input"); - for (var i = 0; i < cbs.length; i++) - cbs[i].onclick = onClick; - - - var button = document.createElement("input"); - button.type = "button"; - button.value = "Hide"; - event.addListener(button, "click", function() { - editor.setDisplaySettings(false); - }); - settingDiv.appendChild(button); - settingDiv.hideButton = button; -} - -// Default startup options. -exports.defaultOptions = { - mode: "javascript", - theme: "textmate", - wrap: "off", - fontSize: "12px", - showGutter: "false", - keybindings: "ace", - showPrintMargin: "false", - useSoftTabs: "true", - showInvisibles: "false" -}; - -}); diff --git a/lib/ace/ext/themelist.js b/lib/ace/ext/themelist.js deleted file mode 100644 index aa8b79d4282..00000000000 --- a/lib/ace/ext/themelist.js +++ /dev/null @@ -1,105 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl - * All rights reserved. - * - * Contributed to Ajax.org under the BSD license. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - - -/** - * Generates a list of themes available when ace was built. - * @fileOverview Generates a list of themes available when ace was built. - * @author - * Matthew Christopher Kastor-Inare III
      - * ☭ Hial Atropa!! ☭ - */ - -define(function(require, exports, module) { -"use strict"; -require("ace/lib/fixoldbrowsers"); - -var themeData = [ - ["Chrome" ], - ["Clouds" ], - ["Crimson Editor" ], - ["Dawn" ], - ["Dreamweaver" ], - ["Eclipse" ], - ["GitHub" ], - ["IPlastic" ], - ["Solarized Light"], - ["TextMate" ], - ["Tomorrow" ], - ["XCode" ], - ["Kuroir"], - ["KatzenMilch"], - ["SQL Server" ,"sqlserver" , "light"], - ["Ambiance" ,"ambiance" , "dark"], - ["Chaos" ,"chaos" , "dark"], - ["Clouds Midnight" ,"clouds_midnight" , "dark"], - ["Dracula" ,"" , "dark"], - ["Cobalt" ,"cobalt" , "dark"], - ["Gruvbox" ,"gruvbox" , "dark"], - ["Green on Black" ,"gob" , "dark"], - ["idle Fingers" ,"idle_fingers" , "dark"], - ["krTheme" ,"kr_theme" , "dark"], - ["Merbivore" ,"merbivore" , "dark"], - ["Merbivore Soft" ,"merbivore_soft" , "dark"], - ["Mono Industrial" ,"mono_industrial" , "dark"], - ["Monokai" ,"monokai" , "dark"], - ["Pastel on dark" ,"pastel_on_dark" , "dark"], - ["Solarized Dark" ,"solarized_dark" , "dark"], - ["Terminal" ,"terminal" , "dark"], - ["Tomorrow Night" ,"tomorrow_night" , "dark"], - ["Tomorrow Night Blue" ,"tomorrow_night_blue" , "dark"], - ["Tomorrow Night Bright","tomorrow_night_bright" , "dark"], - ["Tomorrow Night 80s" ,"tomorrow_night_eighties" , "dark"], - ["Twilight" ,"twilight" , "dark"], - ["Vibrant Ink" ,"vibrant_ink" , "dark"] -]; - - -exports.themesByName = {}; - -/** - * An array containing information about available themes. - */ -exports.themes = themeData.map(function(data) { - var name = data[1] || data[0].replace(/ /g, "_").toLowerCase(); - var theme = { - caption: data[0], - theme: "ace/theme/" + name, - isDark: data[2] == "dark", - name: name - }; - exports.themesByName[name] = theme; - return theme; -}); - -}); - diff --git a/lib/ace/incremental_search.js b/lib/ace/incremental_search.js deleted file mode 100644 index b2cb2d3b900..00000000000 --- a/lib/ace/incremental_search.js +++ /dev/null @@ -1,315 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("./lib/oop"); -var Range = require("./range").Range; -var Search = require("./search").Search; -var SearchHighlight = require("./search_highlight").SearchHighlight; -var iSearchCommandModule = require("./commands/incremental_search_commands"); -var ISearchKbd = iSearchCommandModule.IncrementalSearchKeyboardHandler; - -/** - * @class IncrementalSearch - * - * Implements immediate searching while the user is typing. When incremental - * search is activated, keystrokes into the editor will be used for composing - * a search term. Immediately after every keystroke the search is updated: - * - so-far-matching characters are highlighted - * - the cursor is moved to the next match - * - **/ - - -/** - * - * - * Creates a new `IncrementalSearch` object. - * - * @constructor - **/ -function IncrementalSearch() { - this.$options = {wrap: false, skipCurrent: false}; - this.$keyboardHandler = new ISearchKbd(this); -} - -oop.inherits(IncrementalSearch, Search); - -// regexp handling - -function isRegExp(obj) { - return obj instanceof RegExp; -} - -function regExpToObject(re) { - var string = String(re), - start = string.indexOf('/'), - flagStart = string.lastIndexOf('/'); - return { - expression: string.slice(start+1, flagStart), - flags: string.slice(flagStart+1) - }; -} - -function stringToRegExp(string, flags) { - try { - return new RegExp(string, flags); - } catch (e) { return string; } -} - -function objectToRegExp(obj) { - return stringToRegExp(obj.expression, obj.flags); -} - -// iSearch class - -(function() { - - this.activate = function(ed, backwards) { - this.$editor = ed; - this.$startPos = this.$currentPos = ed.getCursorPosition(); - this.$options.needle = ''; - this.$options.backwards = backwards; - ed.keyBinding.addKeyboardHandler(this.$keyboardHandler); - // we need to completely intercept paste, just registering an event handler does not work - this.$originalEditorOnPaste = ed.onPaste; ed.onPaste = this.onPaste.bind(this); - this.$mousedownHandler = ed.addEventListener('mousedown', this.onMouseDown.bind(this)); - this.selectionFix(ed); - this.statusMessage(true); - }; - - this.deactivate = function(reset) { - this.cancelSearch(reset); - var ed = this.$editor; - ed.keyBinding.removeKeyboardHandler(this.$keyboardHandler); - if (this.$mousedownHandler) { - ed.removeEventListener('mousedown', this.$mousedownHandler); - delete this.$mousedownHandler; - } - ed.onPaste = this.$originalEditorOnPaste; - this.message(''); - }; - - this.selectionFix = function(editor) { - // Fix selection bug: When clicked inside the editor - // editor.selection.$isEmpty is false even if the mouse click did not - // open a selection. This is interpreted by the move commands to - // extend the selection. To only extend the selection when there is - // one, we clear it here - if (editor.selection.isEmpty() && !editor.session.$emacsMark) { - editor.clearSelection(); - } - }; - - this.highlight = function(regexp) { - var sess = this.$editor.session, - hl = sess.$isearchHighlight = sess.$isearchHighlight || sess.addDynamicMarker( - new SearchHighlight(null, "ace_isearch-result", "text")); - hl.setRegexp(regexp); - sess._emit("changeBackMarker"); // force highlight layer redraw - }; - - this.cancelSearch = function(reset) { - var e = this.$editor; - this.$prevNeedle = this.$options.needle; - this.$options.needle = ''; - if (reset) { - e.moveCursorToPosition(this.$startPos); - this.$currentPos = this.$startPos; - } else { - e.pushEmacsMark && e.pushEmacsMark(this.$startPos, false); - } - this.highlight(null); - return Range.fromPoints(this.$currentPos, this.$currentPos); - }; - - this.highlightAndFindWithNeedle = function(moveToNext, needleUpdateFunc) { - if (!this.$editor) return null; - var options = this.$options; - - // get search term - if (needleUpdateFunc) { - options.needle = needleUpdateFunc.call(this, options.needle || '') || ''; - } - if (options.needle.length === 0) { - this.statusMessage(true); - return this.cancelSearch(true); - } - - // try to find the next occurrence and enable highlighting marker - options.start = this.$currentPos; - var session = this.$editor.session, - found = this.find(session), - shouldSelect = this.$editor.emacsMark ? - !!this.$editor.emacsMark() : !this.$editor.selection.isEmpty(); - if (found) { - if (options.backwards) found = Range.fromPoints(found.end, found.start); - this.$editor.selection.setRange(Range.fromPoints(shouldSelect ? this.$startPos : found.end, found.end)); - if (moveToNext) this.$currentPos = found.end; - // highlight after cursor move, so selection works properly - this.highlight(options.re); - } - - this.statusMessage(found); - - return found; - }; - - this.addString = function(s) { - return this.highlightAndFindWithNeedle(false, function(needle) { - if (!isRegExp(needle)) - return needle + s; - var reObj = regExpToObject(needle); - reObj.expression += s; - return objectToRegExp(reObj); - }); - }; - - this.removeChar = function(c) { - return this.highlightAndFindWithNeedle(false, function(needle) { - if (!isRegExp(needle)) - return needle.substring(0, needle.length-1); - var reObj = regExpToObject(needle); - reObj.expression = reObj.expression.substring(0, reObj.expression.length-1); - return objectToRegExp(reObj); - }); - }; - - this.next = function(options) { - // try to find the next occurrence of whatever we have searched for - // earlier. - // options = {[backwards: BOOL], [useCurrentOrPrevSearch: BOOL]} - options = options || {}; - this.$options.backwards = !!options.backwards; - this.$currentPos = this.$editor.getCursorPosition(); - return this.highlightAndFindWithNeedle(true, function(needle) { - return options.useCurrentOrPrevSearch && needle.length === 0 ? - this.$prevNeedle || '' : needle; - }); - }; - - this.onMouseDown = function(evt) { - // when mouse interaction happens then we quit incremental search - this.deactivate(); - return true; - }; - - this.onPaste = function(text) { - this.addString(text); - }; - - this.convertNeedleToRegExp = function() { - return this.highlightAndFindWithNeedle(false, function(needle) { - return isRegExp(needle) ? needle : stringToRegExp(needle, 'ig'); - }); - }; - - this.convertNeedleToString = function() { - return this.highlightAndFindWithNeedle(false, function(needle) { - return isRegExp(needle) ? regExpToObject(needle).expression : needle; - }); - }; - - this.statusMessage = function(found) { - var options = this.$options, msg = ''; - msg += options.backwards ? 'reverse-' : ''; - msg += 'isearch: ' + options.needle; - msg += found ? '' : ' (not found)'; - this.message(msg); - }; - - this.message = function(msg) { - if (this.$editor.showCommandLine) { - this.$editor.showCommandLine(msg); - this.$editor.focus(); - } else { - console.log(msg); - } - }; - -}).call(IncrementalSearch.prototype); - - -exports.IncrementalSearch = IncrementalSearch; - - -/** - * - * Config settings for enabling/disabling [[IncrementalSearch `IncrementalSearch`]]. - * - **/ - -var dom = require('./lib/dom'); -dom.importCssString && dom.importCssString("\ -.ace_marker-layer .ace_isearch-result {\ - position: absolute;\ - z-index: 6;\ - box-sizing: border-box;\ -}\ -div.ace_isearch-result {\ - border-radius: 4px;\ - background-color: rgba(255, 200, 0, 0.5);\ - box-shadow: 0 0 4px rgb(255, 200, 0);\ -}\ -.ace_dark div.ace_isearch-result {\ - background-color: rgb(100, 110, 160);\ - box-shadow: 0 0 4px rgb(80, 90, 140);\ -}", "incremental-search-highlighting"); - -// support for default keyboard handler -var commands = require("./commands/command_manager"); -(function() { - this.setupIncrementalSearch = function(editor, val) { - if (this.usesIncrementalSearch == val) return; - this.usesIncrementalSearch = val; - var iSearchCommands = iSearchCommandModule.iSearchStartCommands; - var method = val ? 'addCommands' : 'removeCommands'; - this[method](iSearchCommands); - }; -}).call(commands.CommandManager.prototype); - -// incremental search config option -var Editor = require("./editor").Editor; -require("./config").defineOptions(Editor.prototype, "editor", { - useIncrementalSearch: { - set: function(val) { - this.keyBinding.$handlers.forEach(function(handler) { - if (handler.setupIncrementalSearch) { - handler.setupIncrementalSearch(this, val); - } - }); - this._emit('incrementalSearchSettingChanged', {isEnabled: val}); - } - } -}); - -}); diff --git a/lib/ace/keyboard/emacs_test.js b/lib/ace/keyboard/emacs_test.js deleted file mode 100644 index 2a30acc08ab..00000000000 --- a/lib/ace/keyboard/emacs_test.js +++ /dev/null @@ -1,173 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") { - require("amd-loader"); - require("../test/mockdom"); -} - -define(function(require, exports, module) { -"use strict"; - -require("../multi_select"); - -var EditSession = require("./../edit_session").EditSession, - Editor = require("./../editor").Editor, - Range = require("./../range").Range, - MockRenderer = require("./../test/mockrenderer").MockRenderer, - emacs = require('./emacs'), - assert = require("./../test/assertions"), - editor, sel; - -function initEditor(docString) { - var doc = new EditSession(docString.split("\n")); - editor = new Editor(new MockRenderer(), doc); - editor.setKeyboardHandler(emacs.handler); - sel = editor.selection; -} - -function print(obj) { - return JSON.stringify(obj, null, 2); -} - -function pluck(arr, what) { - return arr.map(function(ea) { return ea[what]; }); -} - -module.exports = { - - "test: detach removes emacs commands from command manager": function() { - initEditor(''); - assert.ok(!!editor.commands.byName["keyboardQuit"], 'setup error: emacs commands not installed'); - editor.keyBinding.removeKeyboardHandler(editor.getKeyboardHandler()); - assert.ok(!editor.commands.byName["keyboardQuit"], 'emacs commands not removed'); - }, - - "test: keyboardQuit clears selection": function() { - initEditor('foo'); - editor.selectAll(); - editor.execCommand('keyboardQuit'); - assert.ok(editor.selection.isEmpty(), 'selection non-empty'); - }, - - "test: exchangePointAndMark without mark set": function() { - initEditor('foo'); - sel.setRange(Range.fromPoints({row: 0, column: 1}, {row: 0, column: 3})); - editor.execCommand('exchangePointAndMark'); - assert.deepEqual({row: 0, column: 1}, editor.getCursorPosition(), print(editor.getCursorPosition())); - }, - - "test: exchangePointAndMark with mark set": function() { - initEditor('foo'); - editor.pushEmacsMark({row: 0, column: 1}); - editor.pushEmacsMark({row: 0, column: 2}); - editor.execCommand('exchangePointAndMark', {count: 4}); - assert.deepEqual({row: 0, column: 2}, editor.getCursorPosition(), print(editor.getCursorPosition())); - assert.deepEqual([{row: 0, column: 1}, {row: 0, column: 0}], editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing)); - }, - - "test: exchangePointAndMark with selection": function() { - initEditor('foo'); - editor.pushEmacsMark({row: 0, column: 1}); - editor.pushEmacsMark({row: 0, column: 2}); - sel.setRange(Range.fromPoints({row: 0, column: 0}, {row: 0, column: 1}), true); - editor.execCommand('exchangePointAndMark'); - assert.deepEqual({row: 0, column: 1}, editor.getCursorPosition(), print(editor.getCursorPosition())); - assert.deepEqual([{row: 0, column: 1}, {row: 0, column: 2}], editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing)); - }, - - "test: exchangePointAndMark with multi selection": function() { - initEditor('foo\nhello world\n123'); - var ranges = [[{row: 0, column: 0}, {row: 0, column: 3}], - [{row: 1, column: 0}, {row: 1, column: 5}], - [{row: 1, column: 6}, {row: 1, column: 11}]]; - ranges.forEach(function(r) { - sel.addRange(Range.fromPoints(r[0], r[1])); - }); - assert.equal("foo\nhello\nworld", editor.getSelectedText()); - editor.execCommand('exchangePointAndMark'); - assert.equal("foo\nhello\nworld", editor.getSelectedText()); - assert.deepEqual(pluck(ranges, 0), pluck(sel.getAllRanges(), 'cursor'), "selections dir not inverted"); - }, - - "test: exchangePointAndMark with multi cursors": function() { - initEditor('foo\nhello world\n123'); - var ranges = [[{row: 0, column: 0}, {row: 0, column: 3}], - [{row: 1, column: 0}, {row: 1, column: 5}], - [{row: 1, column: 6}, {row: 1, column: 11}]]; - // move cursors to the start of each range and set a mark to its end - // without selecting anything - ranges.forEach(function(r) { - editor.pushEmacsMark(r[1]); - sel.addRange(Range.fromPoints(r[0], r[0])); - }); - assert.deepEqual(pluck(ranges, 0), pluck(sel.getAllRanges(), 'cursor'), print(sel.getAllRanges())); - editor.execCommand('exchangePointAndMark'); - assert.deepEqual(pluck(ranges, 1), pluck(sel.getAllRanges(), 'cursor'), "not inverted: " + print(sel.getAllRanges())); - }, - - "test: setMark with multi cursors": function() { - initEditor('foo\nhello world\n123'); - var positions = [{row: 0, column: 0}, - {row: 1, column: 0}, - {row: 1, column: 6}]; - positions.forEach(function(p) { sel.addRange(Range.fromPoints(p,p)); }); - editor.execCommand('setMark'); - assert.deepEqual(positions, editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing)); - }, - - "test: killLine": function() { - initEditor("foo \n Hello world\n \n 123"); - sel.setRange(new Range(0, 0, 0, 2)); - editor.endOperation(); - editor.execCommand("killLine"); - assert.equal(editor.getValue(),"fo\n Hello world\n \n 123"); - editor.execCommand("killLine"); - assert.equal(editor.getValue(),"fo Hello world\n \n 123"); - editor.execCommand("killLine"); - assert.equal(editor.getValue(),"fo\n \n 123"); - editor.execCommand("killLine"); - assert.equal(editor.getValue(),"fo\n 123"); - editor.execCommand("killLine"); - assert.equal(editor.getValue(),"fo 123"); - editor.execCommand("killLine"); - assert.equal(editor.getValue(),"fo"); - editor.execCommand("killLine"); - editor.execCommand("yank"); - assert.equal(editor.getValue(),"foo \n Hello world\n \n 123"); - } - -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/keyboard/hash_handler.js b/lib/ace/keyboard/hash_handler.js deleted file mode 100644 index 1074fc267bd..00000000000 --- a/lib/ace/keyboard/hash_handler.js +++ /dev/null @@ -1,256 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var keyUtil = require("../lib/keys"); -var useragent = require("../lib/useragent"); -var KEY_MODS = keyUtil.KEY_MODS; - -function HashHandler(config, platform) { - this.platform = platform || (useragent.isMac ? "mac" : "win"); - this.commands = {}; - this.commandKeyBinding = {}; - this.addCommands(config); - this.$singleCommand = true; -} - -function MultiHashHandler(config, platform) { - HashHandler.call(this, config, platform); - this.$singleCommand = false; -} - -MultiHashHandler.prototype = HashHandler.prototype; - -(function() { - - - this.addCommand = function(command) { - if (this.commands[command.name]) - this.removeCommand(command); - - this.commands[command.name] = command; - - if (command.bindKey) - this._buildKeyHash(command); - }; - - this.removeCommand = function(command, keepCommand) { - var name = command && (typeof command === 'string' ? command : command.name); - command = this.commands[name]; - if (!keepCommand) - delete this.commands[name]; - - // exhaustive search is brute force but since removeCommand is - // not a performance critical operation this should be OK - var ckb = this.commandKeyBinding; - for (var keyId in ckb) { - var cmdGroup = ckb[keyId]; - if (cmdGroup == command) { - delete ckb[keyId]; - } else if (Array.isArray(cmdGroup)) { - var i = cmdGroup.indexOf(command); - if (i != -1) { - cmdGroup.splice(i, 1); - if (cmdGroup.length == 1) - ckb[keyId] = cmdGroup[0]; - } - } - } - }; - - this.bindKey = function(key, command, position) { - if (typeof key == "object" && key) { - if (position == undefined) - position = key.position; - key = key[this.platform]; - } - if (!key) - return; - if (typeof command == "function") - return this.addCommand({exec: command, bindKey: key, name: command.name || key}); - - key.split("|").forEach(function(keyPart) { - var chain = ""; - if (keyPart.indexOf(" ") != -1) { - var parts = keyPart.split(/\s+/); - keyPart = parts.pop(); - parts.forEach(function(keyPart) { - var binding = this.parseKeys(keyPart); - var id = KEY_MODS[binding.hashId] + binding.key; - chain += (chain ? " " : "") + id; - this._addCommandToBinding(chain, "chainKeys"); - }, this); - chain += " "; - } - var binding = this.parseKeys(keyPart); - var id = KEY_MODS[binding.hashId] + binding.key; - this._addCommandToBinding(chain + id, command, position); - }, this); - }; - - function getPosition(command) { - return typeof command == "object" && command.bindKey - && command.bindKey.position - || (command.isDefault ? -100 : 0); - } - this._addCommandToBinding = function(keyId, command, position) { - var ckb = this.commandKeyBinding, i; - if (!command) { - delete ckb[keyId]; - } else if (!ckb[keyId] || this.$singleCommand) { - ckb[keyId] = command; - } else { - if (!Array.isArray(ckb[keyId])) { - ckb[keyId] = [ckb[keyId]]; - } else if ((i = ckb[keyId].indexOf(command)) != -1) { - ckb[keyId].splice(i, 1); - } - - if (typeof position != "number") { - position = getPosition(command); - } - - var commands = ckb[keyId]; - for (i = 0; i < commands.length; i++) { - var other = commands[i]; - var otherPos = getPosition(other); - if (otherPos > position) - break; - } - commands.splice(i, 0, command); - } - }; - - this.addCommands = function(commands) { - commands && Object.keys(commands).forEach(function(name) { - var command = commands[name]; - if (!command) - return; - - if (typeof command === "string") - return this.bindKey(command, name); - - if (typeof command === "function") - command = { exec: command }; - - if (typeof command !== "object") - return; - - if (!command.name) - command.name = name; - - this.addCommand(command); - }, this); - }; - - this.removeCommands = function(commands) { - Object.keys(commands).forEach(function(name) { - this.removeCommand(commands[name]); - }, this); - }; - - this.bindKeys = function(keyList) { - Object.keys(keyList).forEach(function(key) { - this.bindKey(key, keyList[key]); - }, this); - }; - - this._buildKeyHash = function(command) { - this.bindKey(command.bindKey, command); - }; - - // accepts keys in the form ctrl+Enter or ctrl-Enter - // keys without modifiers or shift only - this.parseKeys = function(keys) { - var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x;}); - var key = parts.pop(); - - var keyCode = keyUtil[key]; - if (keyUtil.FUNCTION_KEYS[keyCode]) - key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase(); - else if (!parts.length) - return {key: key, hashId: -1}; - else if (parts.length == 1 && parts[0] == "shift") - return {key: key.toUpperCase(), hashId: -1}; - - var hashId = 0; - for (var i = parts.length; i--;) { - var modifier = keyUtil.KEY_MODS[parts[i]]; - if (modifier == null) { - if (typeof console != "undefined") - console.error("invalid modifier " + parts[i] + " in " + keys); - return false; - } - hashId |= modifier; - } - return {key: key, hashId: hashId}; - }; - - this.findKeyCommand = function findKeyCommand(hashId, keyString) { - var key = KEY_MODS[hashId] + keyString; - return this.commandKeyBinding[key]; - }; - - this.handleKeyboard = function(data, hashId, keyString, keyCode) { - if (keyCode < 0) return; - var key = KEY_MODS[hashId] + keyString; - var command = this.commandKeyBinding[key]; - if (data.$keyChain) { - data.$keyChain += " " + key; - command = this.commandKeyBinding[data.$keyChain] || command; - } - - if (command) { - if (command == "chainKeys" || command[command.length - 1] == "chainKeys") { - data.$keyChain = data.$keyChain || key; - return {command: "null"}; - } - } - - if (data.$keyChain) { - if ((!hashId || hashId == 4) && keyString.length == 1) - data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input - else if (hashId == -1 || keyCode > 0) - data.$keyChain = ""; // reset keyChain - } - return {command: command}; - }; - - this.getStatusText = function(editor, data) { - return data.$keyChain || ""; - }; - -}).call(HashHandler.prototype); - -exports.HashHandler = HashHandler; -exports.MultiHashHandler = MultiHashHandler; -}); diff --git a/lib/ace/keyboard/keybinding.js b/lib/ace/keyboard/keybinding.js deleted file mode 100644 index 4879a3b964e..00000000000 --- a/lib/ace/keyboard/keybinding.js +++ /dev/null @@ -1,152 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var keyUtil = require("../lib/keys"); -var event = require("../lib/event"); - -var KeyBinding = function(editor) { - this.$editor = editor; - this.$data = {editor: editor}; - this.$handlers = []; - this.setDefaultHandler(editor.commands); -}; - -(function() { - this.setDefaultHandler = function(kb) { - this.removeKeyboardHandler(this.$defaultHandler); - this.$defaultHandler = kb; - this.addKeyboardHandler(kb, 0); - }; - - this.setKeyboardHandler = function(kb) { - var h = this.$handlers; - if (h[h.length - 1] == kb) - return; - - while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler) - this.removeKeyboardHandler(h[h.length - 1]); - - this.addKeyboardHandler(kb, 1); - }; - - this.addKeyboardHandler = function(kb, pos) { - if (!kb) - return; - if (typeof kb == "function" && !kb.handleKeyboard) - kb.handleKeyboard = kb; - var i = this.$handlers.indexOf(kb); - if (i != -1) - this.$handlers.splice(i, 1); - - if (pos == undefined) - this.$handlers.push(kb); - else - this.$handlers.splice(pos, 0, kb); - - if (i == -1 && kb.attach) - kb.attach(this.$editor); - }; - - this.removeKeyboardHandler = function(kb) { - var i = this.$handlers.indexOf(kb); - if (i == -1) - return false; - this.$handlers.splice(i, 1); - kb.detach && kb.detach(this.$editor); - return true; - }; - - this.getKeyboardHandler = function() { - return this.$handlers[this.$handlers.length - 1]; - }; - - this.getStatusText = function() { - var data = this.$data; - var editor = data.editor; - return this.$handlers.map(function(h) { - return h.getStatusText && h.getStatusText(editor, data) || ""; - }).filter(Boolean).join(" "); - }; - - this.$callKeyboardHandlers = function(hashId, keyString, keyCode, e) { - var toExecute; - var success = false; - var commands = this.$editor.commands; - - for (var i = this.$handlers.length; i--;) { - toExecute = this.$handlers[i].handleKeyboard( - this.$data, hashId, keyString, keyCode, e - ); - if (!toExecute || !toExecute.command) - continue; - - // allow keyboardHandler to consume keys - if (toExecute.command == "null") { - success = true; - } else { - success = commands.exec(toExecute.command, this.$editor, toExecute.args, e); - } - // do not stop input events to not break repeating - if (success && e && hashId != -1 && - toExecute.passEvent != true && toExecute.command.passEvent != true - ) { - event.stopEvent(e); - } - if (success) - break; - } - - if (!success && hashId == -1) { - toExecute = {command: "insertstring"}; - success = commands.exec("insertstring", this.$editor, keyString); - } - - if (success && this.$editor._signal) - this.$editor._signal("keyboardActivity", toExecute); - - return success; - }; - - this.onCommandKey = function(e, hashId, keyCode) { - var keyString = keyUtil.keyCodeToString(keyCode); - this.$callKeyboardHandlers(hashId, keyString, keyCode, e); - }; - - this.onTextInput = function(text) { - this.$callKeyboardHandlers(-1, text); - }; - -}).call(KeyBinding.prototype); - -exports.KeyBinding = KeyBinding; -}); diff --git a/lib/ace/keyboard/keybinding_test.js b/lib/ace/keyboard/keybinding_test.js deleted file mode 100644 index eee6d599311..00000000000 --- a/lib/ace/keyboard/keybinding_test.js +++ /dev/null @@ -1,69 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") { - require("amd-loader"); -} - -define(function(require, exports, module) { -"use strict"; - -var EditSession = require("./../edit_session").EditSession, - Editor = require("./../editor").Editor, - MockRenderer = require("./../test/mockrenderer").MockRenderer, - assert = require("./../test/assertions"), - HashHandler = require('./hash_handler').HashHandler, - keys = require('../lib/keys'), - editor; - -function initEditor(docString) { - var doc = new EditSession(docString.split("\n")); - editor = new Editor(new MockRenderer(), doc); -} - -module.exports = { - - "test: adding a new keyboard handler does not remove the default handler": function() { - initEditor('abc'); - var handler = new HashHandler({'del': 'f1'}); - editor.keyBinding.setKeyboardHandler(handler); - editor.onCommandKey({}, 0, keys['f1']); - assert.equal('bc', editor.getValue(), "binding of new handler"); - editor.onCommandKey({}, 0, keys['delete']); - assert.equal('c', editor.getValue(), "bindings of the old handler should still work"); - } - -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/keyboard/state_handler.js b/lib/ace/keyboard/state_handler.js deleted file mode 100644 index 6859e743bd9..00000000000 --- a/lib/ace/keyboard/state_handler.js +++ /dev/null @@ -1,249 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -// If you're developing a new keymapping and want to get an idea what's going -// on, then enable debugging. -var DEBUG = false; - -function StateHandler(keymapping) { - this.keymapping = this.$buildKeymappingRegex(keymapping); -} - -StateHandler.prototype = { - /* - * Build the RegExp from the keymapping as RegExp can't stored directly - * in the metadata JSON and as the RegExp used to match the keys/buffer - * need to be adapted. - */ - $buildKeymappingRegex: function(keymapping) { - for (var state in keymapping) { - this.$buildBindingsRegex(keymapping[state]); - } - return keymapping; - }, - - $buildBindingsRegex: function(bindings) { - // Escape a given Regex string. - bindings.forEach(function(binding) { - if (binding.key) { - binding.key = new RegExp('^' + binding.key + '$'); - } else if (Array.isArray(binding.regex)) { - if (!('key' in binding)) - binding.key = new RegExp('^' + binding.regex[1] + '$'); - binding.regex = new RegExp(binding.regex.join('') + '$'); - } else if (binding.regex) { - binding.regex = new RegExp(binding.regex + '$'); - } - }); - }, - - $composeBuffer: function(data, hashId, key, e) { - // Initialize the data object. - if (data.state == null || data.buffer == null) { - data.state = "start"; - data.buffer = ""; - } - - var keyArray = []; - if (hashId & 1) keyArray.push("ctrl"); - if (hashId & 8) keyArray.push("command"); - if (hashId & 2) keyArray.push("option"); - if (hashId & 4) keyArray.push("shift"); - if (key) keyArray.push(key); - - var symbolicName = keyArray.join("-"); - var bufferToUse = data.buffer + symbolicName; - - // Don't add the symbolic name to the key buffer if the alt_ key is - // part of the symbolic name. If it starts with alt_, this means - // that the user hit an alt keycombo and there will be a single, - // new character detected after this event, which then will be - // added to the buffer (e.g. alt_j will result in ∆). - // - // We test for 2 and not for & 2 as we only want to exclude the case where - // the option key is pressed alone. - if (hashId != 2) { - data.buffer = bufferToUse; - } - - var bufferObj = { - bufferToUse: bufferToUse, - symbolicName: symbolicName - }; - - if (e) { - bufferObj.keyIdentifier = e.keyIdentifier; - } - - return bufferObj; - }, - - $find: function(data, buffer, symbolicName, hashId, key, keyIdentifier) { - // Holds the command to execute and the args if a command matched. - var result = {}; - - // Loop over all the bindings of the keymap until a match is found. - this.keymapping[data.state].some(function(binding) { - var match; - - // Check if the key matches. - if (binding.key && !binding.key.test(symbolicName)) { - return false; - } - - // Check if the regex matches. - if (binding.regex && !(match = binding.regex.exec(buffer))) { - return false; - } - - // Check if the match function matches. - if (binding.match && !binding.match(buffer, hashId, key, symbolicName, keyIdentifier)) { - return false; - } - - // Check for disallowed matches. - if (binding.disallowMatches) { - for (var i = 0; i < binding.disallowMatches.length; i++) { - if (!!match[binding.disallowMatches[i]]) { - return false; - } - } - } - - // If there is a command to execute, then figure out the - // command and the arguments. - if (binding.exec) { - result.command = binding.exec; - - // Build the arguments. - if (binding.params) { - var value; - result.args = {}; - binding.params.forEach(function(param) { - if (param.match != null && match != null) { - value = match[param.match] || param.defaultValue; - } else { - value = param.defaultValue; - } - - if (param.type === 'number') { - value = parseInt(value); - } - - result.args[param.name] = value; - }); - } - data.buffer = ""; - } - - // Handle the 'then' property. - if (binding.then) { - data.state = binding.then; - data.buffer = ""; - } - - // If no command is set, then execute the "null" fake command. - if (result.command == null) { - result.command = "null"; - } - - if (DEBUG) { - console.log("KeyboardStateMapper#find", binding); - } - return true; - }); - - if (result.command) { - return result; - } else { - data.buffer = ""; - return false; - } - }, - - /* - * This function is called by keyBinding. - */ - handleKeyboard: function(data, hashId, key, keyCode, e) { - if (hashId == -1) - hashId = 0; - // If we pressed any command key but no other key, then ignore the input. - // Otherwise "shift-" is added to the buffer, and later on "shift-g" - // which results in "shift-shift-g" which doesn't make sense. - if (hashId != 0 && (key == "" || key == String.fromCharCode(0))) { - return null; - } - - // Compute the current value of the keyboard input buffer. - var r = this.$composeBuffer(data, hashId, key, e); - var buffer = r.bufferToUse; - var symbolicName = r.symbolicName; - var keyId = r.keyIdentifier; - - r = this.$find(data, buffer, symbolicName, hashId, key, keyId); - if (DEBUG) { - console.log("KeyboardStateMapper#match", buffer, symbolicName, r); - } - - return r; - } -}; - -/* - * This is a useful matching function and therefore is defined here so that - * users of KeyboardStateMapper can use it. - * - * @return {Boolean} If no command key (Command|Option|Shift|Ctrl) is pressed, it - * returns true. If the only the Shift key is pressed + a character - * true is returned as well. Otherwise, false is returned. - * Summing up, the function returns true whenever the user typed - * a normal character on the keyboard and no shortcut. - */ -exports.matchCharacterOnly = function(buffer, hashId, key, symbolicName) { - // If no command keys are pressed, then catch the input. - if (hashId == 0) { - return true; - } - // If only the shift key is pressed and a character key, then - // catch that input as well. - else if ((hashId == 4) && key.length == 1) { - return true; - } - // Otherwise, we let the input got through. - else { - return false; - } -}; - -exports.StateHandler = StateHandler; -}); diff --git a/lib/ace/keyboard/textarea.js b/lib/ace/keyboard/textarea.js deleted file mode 100644 index d0e2088e04d..00000000000 --- a/lib/ace/keyboard/textarea.js +++ /dev/null @@ -1,88 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var HashHandler = require("./hash_handler").HashHandler; -exports.handler = new HashHandler(); - -[{ - bindKey: "Shift-Tab|Tab", - command: "passKeysToBrowser" -}, { - bindKey: {win: "Ctrl-L", mac: "Cmd-L"}, - command: "passKeysToBrowser" -}, { - bindKey: {win: "Ctrl-G", mac: "Cmd-G"}, - command: "gotoline" -}, { - bindKey: {win: "Ctrl-T|Ctrl-Shift-T|Ctrl-K", mac: "Cmd-T|Cmd-Shift-T"}, - // TODO can't used shared passKeysToBrowser command since passEvent from it is ignored - command: { - name: "passKeysToBrowser", - exec: function() {}, - passEvent: true, - readOnly: true - } -}, { - bindKey: {win: "Ctrl-G", mac: "Cmd-G"}, - command: "passKeysToBrowser" -}, { - bindKey: {win: "Ctrl-G", mac: "Cmd-G"}, - command: "passKeysToBrowser" -}, { - command: "golineup", - bindKey: {win: null, mac: "Ctrl-P"} -}, { - command: "golinedown", - bindKey: {win: null, mac: "Ctrl-N"} -}, { - command: "gotoleft", - bindKey: {win: null, mac: "Ctrl-B"} -}, { - command: "gotoright", - bindKey: {win: null, mac: "Ctrl-F"} -}, { - command: "gotolineend", - bindKey: {win: null, mac: "Ctrl-E"} -}, { - command: "gotolinestart", - bindKey: {win: null, mac: "Ctrl-A"} -} -].forEach(function(k) { - var bindKey = k.bindKey; - if (typeof bindKey == "object") - bindKey = bindKey[exports.handler.platform]; - exports.handler.bindKey(bindKey, k.command); -}); -exports.handler.$id = "ace/keyboard/textarea"; - -}); diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js deleted file mode 100644 index 26af126fd3e..00000000000 --- a/lib/ace/keyboard/textinput.js +++ /dev/null @@ -1,517 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var event = require("../lib/event"); -var useragent = require("../lib/useragent"); -var dom = require("../lib/dom"); -var lang = require("../lib/lang"); -var BROKEN_SETDATA = useragent.isChrome < 18; -var USE_IE_MIME_TYPE = useragent.isIE; -var HAS_FOCUS_ARGS = useragent.isChrome > 63; - -var TextInputIOS = require("./textinput_ios").TextInput; -var TextInput = function(parentNode, host) { - if (useragent.isIOS) - return TextInputIOS.call(this, parentNode, host); - - var text = dom.createElement("textarea"); - text.className = "ace_text-input"; - - text.setAttribute("wrap", "off"); - text.setAttribute("autocorrect", "off"); - text.setAttribute("autocapitalize", "off"); - text.setAttribute("spellcheck", false); - - text.style.opacity = "0"; - parentNode.insertBefore(text, parentNode.firstChild); - - // \x01 is displayed on firefox and with \u2028 textarea cursor is visible on ie - var PLACEHOLDER = useragent.isIE ? "\x01\x01" : "\u2028\u2028"; - var PLACEHOLDER_RE = useragent.isIE ? /\x01/g : /\u2028/g; - - var copied = false; - var pasted = false; - var inComposition = false; - var tempStyle = ''; - var isSelectionEmpty = true; - var copyWithEmptySelection = false; - - var commandMode = false; - - // FOCUS - // ie9 throws error if document.activeElement is accessed too soon - try { var isFocused = document.activeElement === text; } catch(e) {} - - event.addListener(text, "blur", function(e) { - host.onBlur(e); - isFocused = false; - }); - event.addListener(text, "focus", function(e) { - isFocused = true; - host.onFocus(e); - resetSelection(); - }); - this.$focusScroll = false; - this.focus = function() { - if (tempStyle || HAS_FOCUS_ARGS || this.$focusScroll == "browser") - return text.focus({ preventScroll: true }); - // getBoundingClientRect on IE throws error if element is not in dom tree - if (!document.documentElement.contains(text)) - return; - var top = text.style.top; - text.style.position = "fixed"; - text.style.top = "0px"; - var isTransformed = text.getBoundingClientRect().top != 0; - var ancestors = []; - if (isTransformed) { - var t = text.parentElement; - while (t && t.nodeType == 1) { - ancestors.push(t); - t.setAttribute("ace_nocontext", true); - if (!t.parentElement && t.getRootNode) - t = t.getRootNode().host; - else - t = t.parentElement; - } - } - text.focus({ preventScroll: true }); - if (isTransformed) { - ancestors.forEach(function(p) { - p.removeAttribute("ace_nocontext"); - }); - } - setTimeout(function() { - text.style.position = ""; - if (text.style.top == "0px") - text.style.top = top; - }, 0); - }; - this.blur = function() { - text.blur(); - }; - this.isFocused = function() { - return isFocused; - }; - - // modifying selection of blured textarea can focus it (chrome mac/linux) - var syncSelection = lang.delayedCall(function() { - isFocused && resetSelection(isSelectionEmpty); - }); - var syncValue = lang.delayedCall(function() { - if (!inComposition) { - text.value = PLACEHOLDER; - isFocused && resetSelection(); - } - }); - - function resetSelection(isEmpty) { - isEmpty = copyWithEmptySelection ? false : isEmpty; - if (inComposition) - return; - - // this prevents infinite recursion on safari 8 - // see https://github.com/ajaxorg/ace/issues/2114 - inComposition = true; - - if (inputHandler) { - var selectionStart = 0; - var selectionEnd = isEmpty ? 0 : text.value.length - 1; - } else { - var selectionStart = isEmpty ? 2 : 1; - var selectionEnd = 2; - } - // on firefox this throws if textarea is hidden - try { - text.setSelectionRange(selectionStart, selectionEnd); - } catch(e){} - - inComposition = false; - } - - function resetValue() { - if (inComposition) - return; - text.value = PLACEHOLDER; - //http://code.google.com/p/chromium/issues/detail?id=76516 - if (useragent.isWebKit) - syncValue.schedule(); - } - - useragent.isWebKit || host.addEventListener('changeSelection', function() { - if (host.selection.isEmpty() != isSelectionEmpty) { - isSelectionEmpty = !isSelectionEmpty; - syncSelection.schedule(); - } - }); - - resetValue(); - if (isFocused) - host.onFocus(); - - - var isAllSelected = function(text) { - return text.selectionStart === 0 && text.selectionEnd === text.value.length; - }; - - var onSelect = function(e) { - if (copied) { - copied = false; - } else if (isAllSelected(text)) { - host.selectAll(); - resetSelection(); - } else if (inputHandler) { - resetSelection(host.selection.isEmpty()); - } - }; - - var inputHandler = null; - this.setInputHandler = function(cb) {inputHandler = cb;}; - this.getInputHandler = function() {return inputHandler;}; - var afterContextMenu = false; - - var sendText = function(data) { - if (inputHandler) { - data = inputHandler(data); - inputHandler = null; - } - if (pasted) { - resetSelection(); - if (data) - host.onPaste(data); - pasted = false; - } else if (data == PLACEHOLDER.charAt(0)) { - if (afterContextMenu) - host.execCommand("del", {source: "ace"}); - else // some versions of android do not fire keydown when pressing backspace - host.execCommand("backspace", {source: "ace"}); - } else { - if (data.substring(0, 2) == PLACEHOLDER) - data = data.substr(2); - else if (data.charAt(0) == PLACEHOLDER.charAt(0)) - data = data.substr(1); - else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) - data = data.slice(0, -1); - // can happen if undo in textarea isn't stopped - if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) - data = data.slice(0, -1); - - if (data) - host.onTextInput(data); - } - if (afterContextMenu) - afterContextMenu = false; - }; - var onInput = function(e) { - // console.log("onInput", inComposition) - if (inComposition) - return; - var data = text.value; - sendText(data); - resetValue(); - }; - - var handleClipboardData = function(e, data, forceIEMime) { - var clipboardData = e.clipboardData || window.clipboardData; - if (!clipboardData || BROKEN_SETDATA) - return; - // using "Text" doesn't work on old webkit but ie needs it - var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain"; - try { - if (data) { - // Safari 5 has clipboardData object, but does not handle setData() - return clipboardData.setData(mime, data) !== false; - } else { - return clipboardData.getData(mime); - } - } catch(e) { - if (!forceIEMime) - return handleClipboardData(e, data, true); - } - }; - - var doCopy = function(e, isCut) { - var data = host.getCopyText(); - if (!data) - return event.preventDefault(e); - - if (handleClipboardData(e, data)) { - isCut ? host.onCut() : host.onCopy(); - event.preventDefault(e); - } else { - copied = true; - text.value = data; - text.select(); - setTimeout(function(){ - copied = false; - resetValue(); - resetSelection(); - isCut ? host.onCut() : host.onCopy(); - }); - } - }; - - var onCut = function(e) { - doCopy(e, true); - }; - - var onCopy = function(e) { - doCopy(e, false); - }; - - var onPaste = function(e) { - var data = handleClipboardData(e); - if (typeof data == "string") { - if (data) - host.onPaste(data, e); - if (useragent.isIE) - setTimeout(resetSelection); - event.preventDefault(e); - } - else { - text.value = ""; - pasted = true; - } - }; - - event.addCommandKeyListener(text, host.onCommandKey.bind(host)); - - event.addListener(text, "select", onSelect); - - event.addListener(text, "input", onInput); - - event.addListener(text, "cut", onCut); - event.addListener(text, "copy", onCopy); - event.addListener(text, "paste", onPaste); - - - // Opera has no clipboard events - if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)) { - event.addListener(parentNode, "keydown", function(e) { - if ((useragent.isMac && !e.metaKey) || !e.ctrlKey) - return; - - switch (e.keyCode) { - case 67: - onCopy(e); - break; - case 86: - onPaste(e); - break; - case 88: - onCut(e); - break; - } - }); - } - - - // COMPOSITION - var onCompositionStart = function(e) { - if (inComposition || !host.onCompositionStart || host.$readOnly) - return; - // console.log("onCompositionStart", inComposition) - inComposition = {}; - inComposition.canUndo = host.session.$undoManager; - host.onCompositionStart(); - setTimeout(onCompositionUpdate, 0); - host.on("mousedown", onCompositionEnd); - if (inComposition.canUndo && !host.selection.isEmpty()) { - host.insert(""); - host.session.markUndoGroup(); - host.selection.clearSelection(); - } - host.session.markUndoGroup(); - }; - - var onCompositionUpdate = function() { - // console.log("onCompositionUpdate", inComposition && JSON.stringify(text.value)) - if (!inComposition || !host.onCompositionUpdate || host.$readOnly) - return; - var val = text.value.replace(PLACEHOLDER_RE, ""); - if (inComposition.lastValue === val) return; - - host.onCompositionUpdate(val); - if (inComposition.lastValue) - host.undo(); - if (inComposition.canUndo) - inComposition.lastValue = val; - if (inComposition.lastValue) { - var r = host.selection.getRange(); - host.insert(inComposition.lastValue); - host.session.markUndoGroup(); - inComposition.range = host.selection.getRange(); - host.selection.setRange(r); - host.selection.clearSelection(); - } - }; - - var onCompositionEnd = function(e) { - if (!host.onCompositionEnd || host.$readOnly) return; - // console.log("onCompositionEnd", inComposition &&inComposition.lastValue) - var c = inComposition; - inComposition = false; - var timer = setTimeout(function() { - timer = null; - var str = text.value.replace(PLACEHOLDER_RE, ""); - // console.log(str, c.lastValue) - if (inComposition) - return; - else if (str == c.lastValue) - resetValue(); - else if (!c.lastValue && str) { - resetValue(); - sendText(str); - } - }); - inputHandler = function compositionInputHandler(str) { - // console.log("onCompositionEnd", str, c.lastValue) - if (timer) - clearTimeout(timer); - str = str.replace(PLACEHOLDER_RE, ""); - if (str == c.lastValue) - return ""; - if (c.lastValue && timer) - host.undo(); - return str; - }; - host.onCompositionEnd(); - host.removeListener("mousedown", onCompositionEnd); - if (e.type == "compositionend" && c.range) { - host.selection.setRange(c.range); - } - // Workaround for #3027, #3045, #3097, #3100, #3249 - var needsOnInput = useragent.isIE || - (useragent.isChrome && useragent.isChrome >= 53) || - (useragent.isWebKit && useragent.isWebKit >= 603); - - if (needsOnInput) { - onInput(); - } - }; - - - - var syncComposition = lang.delayedCall(onCompositionUpdate, 50); - - event.addListener(text, "compositionstart", onCompositionStart); - event.addListener(text, "compositionupdate", function(){syncComposition.schedule();}); - event.addListener(text, "keyup", function(){syncComposition.schedule();}); - event.addListener(text, "keydown", function(){syncComposition.schedule();}); - event.addListener(text, "compositionend", onCompositionEnd); - - this.getElement = function() { - return text; - }; - - this.setCommandMode = function(value) { - commandMode = value; - text.readOnly = false; - }; - - this.setReadOnly = function(readOnly) { - if (!commandMode) - text.readOnly = readOnly; - }; - - this.setCopyWithEmptySelection = function(value) { - copyWithEmptySelection = value; - }; - - this.onContextMenu = function(e) { - afterContextMenu = true; - resetSelection(host.selection.isEmpty()); - host._emit("nativecontextmenu", {target: host, domEvent: e}); - this.moveToMouse(e, true); - }; - - this.moveToMouse = function(e, bringToFront) { - if (!tempStyle) - tempStyle = text.style.cssText; - text.style.cssText = (bringToFront ? "z-index:100000;" : "") - + "height:" + text.style.height + ";" - + (useragent.isIE ? "opacity:0.1;" : ""); - - var rect = host.container.getBoundingClientRect(); - var style = dom.computedStyle(host.container); - var top = rect.top + (parseInt(style.borderTopWidth) || 0); - var left = rect.left + (parseInt(rect.borderLeftWidth) || 0); - var maxTop = rect.bottom - top - text.clientHeight -2; - var move = function(e) { - text.style.left = e.clientX - left - 2 + "px"; - text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px"; - }; - move(e); - - if (e.type != "mousedown") - return; - - if (host.renderer.$keepTextAreaAtCursor) - host.renderer.$keepTextAreaAtCursor = null; - - clearTimeout(closeTimeout); - // on windows context menu is opened after mouseup - if (useragent.isWin) - event.capture(host.container, move, onContextMenuClose); - }; - - this.onContextMenuClose = onContextMenuClose; - var closeTimeout; - function onContextMenuClose() { - clearTimeout(closeTimeout); - closeTimeout = setTimeout(function () { - if (tempStyle) { - text.style.cssText = tempStyle; - tempStyle = ''; - } - if (host.renderer.$keepTextAreaAtCursor == null) { - host.renderer.$keepTextAreaAtCursor = true; - host.renderer.$moveTextAreaToCursor(); - } - }, 0); - } - - var onContextMenu = function(e) { - host.textInput.onContextMenu(e); - onContextMenuClose(); - }; - event.addListener(text, "mouseup", onContextMenu); - event.addListener(text, "mousedown", function(e) { - e.preventDefault(); - onContextMenuClose(); - }); - event.addListener(host.renderer.scroller, "contextmenu", onContextMenu); - event.addListener(text, "contextmenu", onContextMenu); -}; - -exports.TextInput = TextInput; -}); diff --git a/lib/ace/keyboard/textinput_ios.js b/lib/ace/keyboard/textinput_ios.js deleted file mode 100644 index 12f6acebd2b..00000000000 --- a/lib/ace/keyboard/textinput_ios.js +++ /dev/null @@ -1,527 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var event = require("../lib/event"); -var useragent = require("../lib/useragent"); -var dom = require("../lib/dom"); -var lang = require("../lib/lang"); -var KEYS = require("../lib/keys"); -var MODS = KEYS.KEY_MODS; -var BROKEN_SETDATA = useragent.isChrome < 18; -var USE_IE_MIME_TYPE = useragent.isIE; - -var TextInput = function(parentNode, host) { - var self = this; - var text = dom.createElement("textarea"); - text.className = useragent.isIOS ? "ace_text-input ace_text-input-ios" : "ace_text-input"; - - if (useragent.isTouchPad) - text.setAttribute("x-palm-disable-auto-cap", true); - - text.setAttribute("wrap", "off"); - text.setAttribute("autocorrect", "off"); - text.setAttribute("autocapitalize", "off"); - text.setAttribute("spellcheck", false); - - text.style.opacity = "0"; - parentNode.insertBefore(text, parentNode.firstChild); - - var PLACEHOLDER = "\n aaaa a\n"; - - var copied = false; - var cut = false; - var pasted = false; - var inComposition = false; - var tempStyle = ''; - var isSelectionEmpty = true; - - // FOCUS - // ie9 throws error if document.activeElement is accessed too soon - try { var isFocused = document.activeElement === text; } catch(e) {} - - event.addListener(text, "blur", function(e) { - host.onBlur(e); - isFocused = false; - }); - event.addListener(text, "focus", function(e) { - isFocused = true; - host.onFocus(e); - resetSelection(); - }); - this.focus = function() { - if (tempStyle) return text.focus(); - text.style.position = "fixed"; - text.focus(); - }; - this.blur = function() { - text.blur(); - }; - this.isFocused = function() { - return isFocused; - }; - - // modifying selection of blured textarea can focus it (chrome mac/linux) - var syncSelection = lang.delayedCall(function() { - isFocused && resetSelection(isSelectionEmpty); - }); - var syncValue = lang.delayedCall(function() { - if (!inComposition) { - text.value = PLACEHOLDER; - isFocused && resetSelection(); - } - }); - - function resetSelection(isEmpty) { - if (inComposition) - return; - - // this prevents infinite recursion on safari 8 - // see https://github.com/ajaxorg/ace/issues/2114 - inComposition = true; - - if (inputHandler) { - selectionStart = 0; - selectionEnd = isEmpty ? 0 : text.value.length - 1; - } else { - var selectionStart = 4; - var selectionEnd = 5; - } - // on firefox this throws if textarea is hidden - try { - text.setSelectionRange(selectionStart, selectionEnd); - } catch(e) {} - - inComposition = false; - } - - function resetValue() { - if (inComposition) - return; - text.value = PLACEHOLDER; - //http://code.google.com/p/chromium/issues/detail?id=76516 - if (useragent.isWebKit) - syncValue.schedule(); - } - - useragent.isWebKit || host.addEventListener('changeSelection', function() { - if (host.selection.isEmpty() != isSelectionEmpty) { - isSelectionEmpty = !isSelectionEmpty; - syncSelection.schedule(); - } - }); - - resetValue(); - if (isFocused) - host.onFocus(); - - - var isAllSelected = function(text) { - return text.selectionStart === 0 && text.selectionEnd === text.value.length; - }; - - var onSelect = function(e) { - if (isAllSelected(text)) { - host.selectAll(); - resetSelection(); - } else if (inputHandler) { - resetSelection(host.selection.isEmpty()); - } - }; - - var inputHandler = null; - this.setInputHandler = function(cb) {inputHandler = cb;}; - this.getInputHandler = function() {return inputHandler;}; - var afterContextMenu = false; - - var sendText = function(data) { - if (text.selectionStart === 4 && text.selectionEnd === 5) { - return; - } - if (inputHandler) { - data = inputHandler(data); - inputHandler = null; - } - if (pasted) { - resetSelection(); - if (data) - host.onPaste(data); - pasted = false; - } else if (data == PLACEHOLDER.substr(0) && text.selectionStart === 4) { - if (afterContextMenu) - host.execCommand("del", {source: "ace"}); - else // some versions of android do not fire keydown when pressing backspace - host.execCommand("backspace", {source: "ace"}); - } else if (!copied) { - if (data.substring(0, 9) == PLACEHOLDER && data.length > PLACEHOLDER.length) - data = data.substr(9); - else if (data.substr(0, 4) == PLACEHOLDER.substr(0, 4)) - data = data.substr(4, data.length - PLACEHOLDER.length + 1); - else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) - data = data.slice(0, -1); - // can happen if undo in textarea isn't stopped - if (data == PLACEHOLDER.charAt(0)) { - // Do nothing - } else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) - data = data.slice(0, -1); - - if (data) - host.onTextInput(data); - } - if (copied) { - copied = false; - } - if (afterContextMenu) - afterContextMenu = false; - }; - var onInput = function(e) { - // console.log("onInput", inComposition) - if (inComposition) - return; - var data = text.value; - sendText(data); - resetValue(); - }; - - var handleClipboardData = function(e, data, forceIEMime) { - var clipboardData = e.clipboardData || window.clipboardData; - if (!clipboardData || BROKEN_SETDATA) - return; - // using "Text" doesn't work on old webkit but ie needs it - var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain"; - try { - if (data) { - // Safari 5 has clipboardData object, but does not handle setData() - return clipboardData.setData(mime, data) !== false; - } else { - return clipboardData.getData(mime); - } - } catch(e) { - if (!forceIEMime) - return handleClipboardData(e, data, true); - } - }; - - var doCopy = function(e, isCut) { - var data = host.getCopyText(); - if (!data) - return event.preventDefault(e); - - if (handleClipboardData(e, data)) { - if (useragent.isIOS) { - cut = isCut; - text.value = "\n aa" + data + "a a\n"; - text.setSelectionRange(4, 4 + data.length); - copied = { - value: data - }; - } - isCut ? host.onCut() : host.onCopy(); - if (!useragent.isIOS) event.preventDefault(e); - } else { - copied = true; - text.value = data; - text.select(); - setTimeout(function(){ - copied = false; - resetValue(); - resetSelection(); - isCut ? host.onCut() : host.onCopy(); - }); - } - }; - - var onCut = function(e) { - doCopy(e, true); - }; - - var onCopy = function(e) { - doCopy(e, false); - }; - - var onPaste = function(e) { - var data = handleClipboardData(e); - if (typeof data == "string") { - if (data) - host.onPaste(data, e); - if (useragent.isIE) - setTimeout(resetSelection); - event.preventDefault(e); - } - else { - text.value = ""; - pasted = true; - } - }; - - event.addCommandKeyListener(text, host.onCommandKey.bind(host)); - - event.addListener(text, "select", onSelect); - - event.addListener(text, "input", onInput); - - event.addListener(text, "cut", onCut); - event.addListener(text, "copy", onCopy); - event.addListener(text, "paste", onPaste); - - - // COMPOSITION - var onCompositionStart = function(e) { - if (inComposition || !host.onCompositionStart || host.$readOnly) - return; - // console.log("onCompositionStart", inComposition) - inComposition = {}; - inComposition.canUndo = host.session.$undoManager; - host.onCompositionStart(); - setTimeout(onCompositionUpdate, 0); - host.on("mousedown", onCompositionEnd); - if (inComposition.canUndo && !host.selection.isEmpty()) { - host.insert(""); - host.session.markUndoGroup(); - host.selection.clearSelection(); - } - host.session.markUndoGroup(); - }; - - var onCompositionUpdate = function() { - // console.log("onCompositionUpdate", inComposition && JSON.stringify(text.value)) - if (!inComposition || !host.onCompositionUpdate || host.$readOnly) - return; - var val = text.value.replace(/\x01/g, ""); - if (inComposition.lastValue === val) return; - - host.onCompositionUpdate(val); - if (inComposition.lastValue) - host.undo(); - if (inComposition.canUndo) - inComposition.lastValue = val; - if (inComposition.lastValue) { - var r = host.selection.getRange(); - host.insert(inComposition.lastValue); - host.session.markUndoGroup(); - inComposition.range = host.selection.getRange(); - host.selection.setRange(r); - host.selection.clearSelection(); - } - }; - - var onCompositionEnd = function(e) { - if (!host.onCompositionEnd || host.$readOnly) return; - // console.log("onCompositionEnd", inComposition &&inComposition.lastValue) - var c = inComposition; - inComposition = false; - var timer = setTimeout(function() { - timer = null; - var str = text.value.replace(/\x01/g, ""); - // console.log(str, c.lastValue) - if (inComposition) - return; - else if (str == c.lastValue) - resetValue(); - else if (!c.lastValue && str) { - resetValue(); - sendText(str); - } - }); - inputHandler = function compositionInputHandler(str) { - // console.log("onCompositionEnd", str, c.lastValue) - if (timer) - clearTimeout(timer); - str = str.replace(/\x01/g, ""); - if (str == c.lastValue) - return ""; - if (c.lastValue && timer) - host.undo(); - return str; - }; - host.onCompositionEnd(); - host.removeListener("mousedown", onCompositionEnd); - if (e.type == "compositionend" && c.range) { - host.selection.setRange(c.range); - } - // Workaround for #3027, #3045, #3097, #3100, #3249 - var needsOnInput = - (!!useragent.isChrome && useragent.isChrome >= 53) || - (!!useragent.isWebKit && useragent.isWebKit >= 603); - - if (needsOnInput) { - onInput(); - } - }; - - - - var syncComposition = lang.delayedCall(onCompositionUpdate, 50); - - event.addListener(text, "compositionstart", onCompositionStart); - event.addListener(text, "compositionupdate", function(){syncComposition.schedule();}); - event.addListener(text, "keyup", function(){syncComposition.schedule();}); - event.addListener(text, "keydown", function(){syncComposition.schedule();}); - event.addListener(text, "compositionend", onCompositionEnd); - - this.getElement = function() { - return text; - }; - - this.setReadOnly = function(readOnly) { - text.readOnly = readOnly; - }; - - this.onContextMenu = function(e) { - afterContextMenu = true; - resetSelection(host.selection.isEmpty()); - host._emit("nativecontextmenu", {target: host, domEvent: e}); - this.moveToMouse(e, true); - }; - - this.moveToMouse = function(e, bringToFront) { - if (!tempStyle) - tempStyle = text.style.cssText; - text.style.cssText = (bringToFront ? "z-index:100000;" : "") - + "height:" + text.style.height + ";" - + (useragent.isIE ? "opacity:0.1;" : ""); - - var rect = host.container.getBoundingClientRect(); - var style = dom.computedStyle(host.container); - var top = rect.top + (parseInt(style.borderTopWidth) || 0); - var left = rect.left + (parseInt(rect.borderLeftWidth) || 0); - var maxTop = rect.bottom - top - text.clientHeight -2; - var move = function(e) { - text.style.left = e.clientX - left - 2 + "px"; - text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px"; - }; - move(e); - - if (e.type != "mousedown") - return; - - if (host.renderer.$keepTextAreaAtCursor) - host.renderer.$keepTextAreaAtCursor = null; - - clearTimeout(closeTimeout); - // on windows context menu is opened after mouseup - if (useragent.isWin) - event.capture(host.container, move, onContextMenuClose); - }; - - this.onContextMenuClose = onContextMenuClose; - var closeTimeout; - function onContextMenuClose() { - clearTimeout(closeTimeout); - closeTimeout = setTimeout(function () { - if (tempStyle) { - text.style.cssText = tempStyle; - tempStyle = ''; - } - if (host.renderer.$keepTextAreaAtCursor == null) { - host.renderer.$keepTextAreaAtCursor = true; - host.renderer.$moveTextAreaToCursor(); - } - }, 0); - } - - var onContextMenu = function(e) { - host.textInput.onContextMenu(e); - onContextMenuClose(); - }; - event.addListener(text, "mouseup", onContextMenu); - event.addListener(text, "mousedown", function(e) { - e.preventDefault(); - onContextMenuClose(); - }); - event.addListener(host.renderer.scroller, "contextmenu", onContextMenu); - event.addListener(text, "contextmenu", onContextMenu); - - if (useragent.isIOS) { - var typingResetTimeout = null; - var typing = false; - - parentNode.addEventListener("keydown", function (e) { - if (typingResetTimeout) clearTimeout(typingResetTimeout); - typing = true; - }); - - parentNode.addEventListener("keyup", function (e) { - typingResetTimeout = setTimeout(function () { - typing = false; - }, 100); - }); - - // IOS doesn't fire events for arrow keys, but this unique hack changes everything! - var detectArrowKeys = function(e) { - if (document.activeElement !== text) return; - if (typing) return; - - if (cut) { - return setTimeout(function () { - cut = false; - }, 100); - } - var selectionStart = text.selectionStart; - var selectionEnd = text.selectionEnd; - text.setSelectionRange(4, 5); - if (selectionStart == selectionEnd) { - switch (selectionStart) { - case 0: host.onCommandKey(null, 0, KEYS.up); break; - case 1: host.onCommandKey(null, 0, KEYS.home); break; - case 2: host.onCommandKey(null, MODS.option, KEYS.left); break; - case 4: host.onCommandKey(null, 0, KEYS.left); break; - case 5: host.onCommandKey(null, 0, KEYS.right); break; - case 7: host.onCommandKey(null, MODS.option, KEYS.right); break; - case 8: host.onCommandKey(null, 0, KEYS.end); break; - case 9: host.onCommandKey(null, 0, KEYS.down); break; - } - } else { - switch (selectionEnd) { - case 6: host.onCommandKey(null, MODS.shift, KEYS.right); break; - case 7: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.right); break; - case 8: host.onCommandKey(null, MODS.shift, KEYS.end); break; - case 9: host.onCommandKey(null, MODS.shift, KEYS.down); break; - } - switch (selectionStart) { - case 0: host.onCommandKey(null, MODS.shift, KEYS.up); break; - case 1: host.onCommandKey(null, MODS.shift, KEYS.home); break; - case 2: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.left); break; - case 3: host.onCommandKey(null, MODS.shift, KEYS.left); break; - } - } - }; - // On iOS, "selectionchange" can only be attached to the document object... - document.addEventListener("selectionchange", detectArrowKeys); - host.on("destroy", function() { - document.removeEventListener("selectionchange", detectArrowKeys); - }); - } -}; - -exports.TextInput = TextInput; -}); diff --git a/lib/ace/keyboard/vim.js b/lib/ace/keyboard/vim.js deleted file mode 100644 index 3ecf0d9fff5..00000000000 --- a/lib/ace/keyboard/vim.js +++ /dev/null @@ -1,6361 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -/** - * Supported keybindings: - * Too many to list. Refer to defaultKeyMap below. - * - * Supported Ex commands: - * Refer to defaultExCommandMap below. - * - * Registers: unnamed, -, a-z, A-Z, 0-9 - * (Does not respect the special case for number registers when delete - * operator is made with these commands: %, (, ), , /, ?, n, N, {, } ) - * TODO: Implement the remaining registers. - * - * Marks: a-z, A-Z, and 0-9 - * TODO: Implement the remaining special marks. They have more complex - * behavior. - * - * Events: - * 'vim-mode-change' - raised on the editor anytime the current mode changes, - * Event object: {mode: "visual", subMode: "linewise"} - * - * Code structure: - * 1. Default keymap - * 2. Variable declarations and short basic helpers - * 3. Instance (External API) implementation - * 4. Internal state tracking objects (input state, counter) implementation - * and instantiation - * 5. Key handler (the main command dispatcher) implementation - * 6. Motion, operator, and action implementations - * 7. Helper functions for the key handler, motions, operators, and actions - * 8. Set up Vim to work as a keymap for CodeMirror. - * 9. Ex command implementations. - */ - -define(function(require, exports, module) { - 'use strict'; - - function log() { - var d = ""; - function format(p) { - if (typeof p != "object") - return p + ""; - if ("line" in p) { - return p.line + ":" + p.ch; - } - if ("anchor" in p) { - return format(p.anchor) + "->" + format(p.head); - } - if (Array.isArray(p)) - return "[" + p.map(function(x) { - return format(x); - }) + "]"; - return JSON.stringify(p); - } - for (var i = 0; i < arguments.length; i++) { - var p = arguments[i]; - var f = format(p); - d += f + " "; - } - console.log(d); - } - var Range = require("../range").Range; - var EventEmitter = require("../lib/event_emitter").EventEmitter; - var dom = require("../lib/dom"); - var oop = require("../lib/oop"); - var KEYS = require("../lib/keys"); - var event = require("../lib/event"); - var Search = require("../search").Search; - var useragent = require("../lib/useragent"); - var SearchHighlight = require("../search_highlight").SearchHighlight; - var multiSelectCommands = require("../commands/multi_select_commands"); - var TextModeTokenRe = require("../mode/text").Mode.prototype.tokenRe; - require("../multi_select"); - - var CodeMirror = function(ace) { - this.ace = ace; - this.state = {}; - this.marks = {}; - this.$uid = 0; - this.onChange = this.onChange.bind(this); - this.onSelectionChange = this.onSelectionChange.bind(this); - this.onBeforeEndOperation = this.onBeforeEndOperation.bind(this); - this.ace.on('change', this.onChange); - this.ace.on('changeSelection', this.onSelectionChange); - this.ace.on('beforeEndOperation', this.onBeforeEndOperation); - }; - CodeMirror.Pos = function(line, ch) { - if (!(this instanceof Pos)) return new Pos(line, ch); - this.line = line; this.ch = ch; - }; - CodeMirror.defineOption = function(name, val, setter) {}; - CodeMirror.commands = { - redo: function(cm) { cm.ace.redo(); }, - undo: function(cm) { cm.ace.undo(); }, - newlineAndIndent: function(cm) { cm.ace.insert("\n"); } - }; - CodeMirror.keyMap = {}; - CodeMirror.addClass = CodeMirror.rmClass = function() {}; - CodeMirror.e_stop = CodeMirror.e_preventDefault = event.stopEvent; - CodeMirror.keyName = function(e) { - var key = (KEYS[e.keyCode] || e.key || ""); - if (key.length == 1) key = key.toUpperCase(); - key = event.getModifierString(e).replace(/(^|-)\w/g, function(m) { - return m.toUpperCase(); - }) + key; - return key; - }; - CodeMirror.keyMap['default'] = function(key) { - return function(cm) { - var cmd = cm.ace.commands.commandKeyBinding[key.toLowerCase()]; - return cmd && cm.ace.execCommand(cmd) !== false; - }; - }; - CodeMirror.lookupKey = function lookupKey(key, map, handle) { - if (typeof map == "string") - map = CodeMirror.keyMap[map]; - var found = typeof map == "function" ? map(key) : map[key]; - if (found === false) return "nothing"; - if (found === "...") return "multi"; - if (found != null && handle(found)) return "handled"; - - if (map.fallthrough) { - if (!Array.isArray(map.fallthrough)) - return lookupKey(key, map.fallthrough, handle); - for (var i = 0; i < map.fallthrough.length; i++) { - var result = lookupKey(key, map.fallthrough[i], handle); - if (result) return result; - } - } - }; - - CodeMirror.signal = function(o, name, e) { return o._signal(name, e) }; - CodeMirror.on = event.addListener; - CodeMirror.off = event.removeListener; - CodeMirror.isWordChar = function(ch) { - if (ch < "\x7f") return /^\w$/.test(ch); - TextModeTokenRe.lastIndex = 0; - return TextModeTokenRe.test(ch); - }; - -(function() { - oop.implement(CodeMirror.prototype, EventEmitter); - - this.destroy = function() { - this.ace.off('change', this.onChange); - this.ace.off('changeSelection', this.onSelectionChange); - this.ace.off('beforeEndOperation', this.onBeforeEndOperation); - this.removeOverlay(); - }; - this.virtualSelectionMode = function() { - return this.ace.inVirtualSelectionMode && this.ace.selection.index; - }; - this.onChange = function(delta) { - var change = { text: delta.action[0] == 'i' ? delta.lines : [] }; - var curOp = this.curOp = this.curOp || {}; - if (!curOp.changeHandlers) - curOp.changeHandlers = this._eventRegistry["change"] && this._eventRegistry["change"].slice(); - if (this.virtualSelectionMode()) return; - if (!curOp.lastChange) { - curOp.lastChange = curOp.change = change; - } else { - curOp.lastChange.next = curOp.lastChange = change; - } - this.$updateMarkers(delta); - }; - this.onSelectionChange = function() { - var curOp = this.curOp = this.curOp || {}; - if (!curOp.cursorActivityHandlers) - curOp.cursorActivityHandlers = this._eventRegistry["cursorActivity"] && this._eventRegistry["cursorActivity"].slice(); - this.curOp.cursorActivity = true; - if (this.ace.inMultiSelectMode) { - this.ace.keyBinding.removeKeyboardHandler(multiSelectCommands.keyboardHandler); - } - }; - this.operation = function(fn, force) { - if (!force && this.curOp || force && this.curOp && this.curOp.force) { - return fn(); - } - if (force || !this.ace.curOp) { - if (this.curOp) - this.onBeforeEndOperation(); - } - if (!this.ace.curOp) { - var prevOp = this.ace.prevOp; - this.ace.startOperation({ - command: { name: "vim", scrollIntoView: "cursor" } - }); - } - var curOp = this.curOp = this.curOp || {}; - this.curOp.force = force; - var result = fn(); - if (this.ace.curOp && this.ace.curOp.command.name == "vim") { - this.ace.endOperation(); - if (!curOp.cursorActivity && !curOp.lastChange && prevOp) - this.ace.prevOp = prevOp; - } - if (force || !this.ace.curOp) { - if (this.curOp) - this.onBeforeEndOperation(); - } - return result; - }; - this.onBeforeEndOperation = function() { - var op = this.curOp; - if (op) { - if (op.change) { this.signal("change", op.change, op); } - if (op && op.cursorActivity) { this.signal("cursorActivity", null, op); } - this.curOp = null; - } - }; - - this.signal = function(eventName, e, handlers) { - var listeners = handlers ? handlers[eventName + "Handlers"] - : (this._eventRegistry || {})[eventName]; - if (!listeners) - return; - listeners = listeners.slice(); - for (var i=0; i 0) { - point.row += rowShift; - point.column += point.row == end.row ? colShift : 0; - continue; - } - if (!isInsert && cmp2 <= 0) { - point.row = start.row; - point.column = start.column; - if (cmp2 === 0) - point.bias = 1; - } - } - }; - var Marker = function(cm, id, row, column) { - this.cm = cm; - this.id = id; - this.row = row; - this.column = column; - cm.marks[this.id] = this; - }; - Marker.prototype.clear = function() { delete this.cm.marks[this.id] }; - Marker.prototype.find = function() { return toCmPos(this) }; - this.setBookmark = function(cursor, options) { - var bm = new Marker(this, this.$uid++, cursor.line, cursor.ch); - if (!options || !options.insertLeft) - bm.$insertRight = true; - this.marks[bm.id] = bm; - return bm; - }; - this.moveH = function(increment, unit) { - if (unit == 'char') { - var sel = this.ace.selection; - sel.clearSelection(); - sel.moveCursorBy(0, increment); - } - }; - this.findPosV = function(start, amount, unit, goalColumn) { - if (unit == 'page') { - var renderer = this.ace.renderer; - var config = renderer.layerConfig; - amount = amount * Math.floor(config.height / config.lineHeight); - unit = 'line'; - } - if (unit == 'line') { - var screenPos = this.ace.session.documentToScreenPosition(start.line, start.ch); - if (goalColumn != null) - screenPos.column = goalColumn; - screenPos.row += amount; - // not what codemirror does but vim mode needs only this - screenPos.row = Math.min(Math.max(0, screenPos.row), this.ace.session.getScreenLength() - 1); - var pos = this.ace.session.screenToDocumentPosition(screenPos.row, screenPos.column); - return toCmPos(pos); - } else { - debugger; - } - }; - this.charCoords = function(pos, mode) { - if (mode == 'div' || !mode) { - var sc = this.ace.session.documentToScreenPosition(pos.line, pos.ch); - return {left: sc.column, top: sc.row}; - }if (mode == 'local') { - var renderer = this.ace.renderer; - var sc = this.ace.session.documentToScreenPosition(pos.line, pos.ch); - var lh = renderer.layerConfig.lineHeight; - var cw = renderer.layerConfig.characterWidth; - var top = lh * sc.row; - return {left: sc.column * cw, top: top, bottom: top + lh}; - } - }; - this.coordsChar = function(pos, mode) { - var renderer = this.ace.renderer; - if (mode == 'local') { - var row = Math.max(0, Math.floor(pos.top / renderer.lineHeight)); - var col = Math.max(0, Math.floor(pos.left / renderer.characterWidth)); - var ch = renderer.session.screenToDocumentPosition(row, col); - return toCmPos(ch); - } else if (mode == 'div') { - throw "not implemented"; - } - }; - this.getSearchCursor = function(query, pos, caseFold) { - var caseSensitive = false; - var isRegexp = false; - if (query instanceof RegExp && !query.global) { - caseSensitive = !query.ignoreCase; - query = query.source; - isRegexp = true; - } - var search = new Search(); - if (pos.ch == undefined) pos.ch = Number.MAX_VALUE; - var acePos = {row: pos.line, column: pos.ch}; - var cm = this; - var last = null; - return { - findNext: function() { return this.find(false) }, - findPrevious: function() {return this.find(true) }, - find: function(back) { - search.setOptions({ - needle: query, - caseSensitive: caseSensitive, - wrap: false, - backwards: back, - regExp: isRegexp, - start: last || acePos - }); - var range = search.find(cm.ace.session); - if (range && range.isEmpty()) { - if (cm.getLine(range.start.row).length == range.start.column) { - search.$options.start = range; - range = search.find(cm.ace.session); - } - } - last = range; - return last; - }, - from: function() { return last && toCmPos(last.start) }, - to: function() { return last && toCmPos(last.end) }, - replace: function(text) { - if (last) { - last.end = cm.ace.session.doc.replace(last, text); - } - } - }; - }; - this.scrollTo = function(x, y) { - var renderer = this.ace.renderer; - var config = renderer.layerConfig; - var maxHeight = config.maxHeight; - maxHeight -= (renderer.$size.scrollerHeight - renderer.lineHeight) * renderer.$scrollPastEnd; - if (y != null) this.ace.session.setScrollTop(Math.max(0, Math.min(y, maxHeight))); - if (x != null) this.ace.session.setScrollLeft(Math.max(0, Math.min(x, config.width))); - }; - this.scrollInfo = function() { return 0; }; - this.scrollIntoView = function(pos, margin) { - if (pos) { - var renderer = this.ace.renderer; - var viewMargin = { "top": 0, "bottom": margin }; - renderer.scrollCursorIntoView(toAcePos(pos), - (renderer.lineHeight * 2) / renderer.$size.scrollerHeight, viewMargin); - } - }; - this.getLine = function(row) { return this.ace.session.getLine(row) }; - this.getRange = function(s, e) { - return this.ace.session.getTextRange(new Range(s.line, s.ch, e.line, e.ch)); - }; - this.replaceRange = function(text, s, e) { - if (!e) e = s; - return this.ace.session.replace(new Range(s.line, s.ch, e.line, e.ch), text); - }; - this.replaceSelections = function(p) { - var sel = this.ace.selection; - if (this.ace.inVirtualSelectionMode) { - this.ace.session.replace(sel.getRange(), p[0] || ""); - return; - } - sel.inVirtualSelectionMode = true; - var ranges = sel.rangeList.ranges; - if (!ranges.length) ranges = [this.ace.multiSelect.getRange()]; - for (var i = ranges.length; i--;) - this.ace.session.replace(ranges[i], p[i] || ""); - sel.inVirtualSelectionMode = false; - }; - this.getSelection = function() { - return this.ace.getSelectedText(); - }; - this.getSelections = function() { - return this.listSelections().map(function(x) { - return this.getRange(x.anchor, x.head); - }, this); - }; - this.getInputField = function() { - return this.ace.textInput.getElement(); - }; - this.getWrapperElement = function() { - return this.ace.containter; - }; - var optMap = { - indentWithTabs: "useSoftTabs", - indentUnit: "tabSize", - tabSize: "tabSize", - firstLineNumber: "firstLineNumber", - readOnly: "readOnly" - }; - this.setOption = function(name, val) { - this.state[name] = val; - switch (name) { - case 'indentWithTabs': - name = optMap[name]; - val = !val; - break; - default: - name = optMap[name]; - } - if (name) - this.ace.setOption(name, val); - }; - this.getOption = function(name, val) { - var aceOpt = optMap[name]; - if (aceOpt) - val = this.ace.getOption(aceOpt); - switch (name) { - case 'indentWithTabs': - name = optMap[name]; - return !val; - } - return aceOpt ? val : this.state[name]; - }; - this.toggleOverwrite = function(on) { - this.state.overwrite = on; - return this.ace.setOverwrite(on); - }; - this.addOverlay = function(o) { - if (!this.$searchHighlight || !this.$searchHighlight.session) { - var highlight = new SearchHighlight(null, "ace_highlight-marker", "text"); - var marker = this.ace.session.addDynamicMarker(highlight); - highlight.id = marker.id; - highlight.session = this.ace.session; - highlight.destroy = function(o) { - highlight.session.off("change", highlight.updateOnChange); - highlight.session.off("changeEditor", highlight.destroy); - highlight.session.removeMarker(highlight.id); - highlight.session = null; - }; - highlight.updateOnChange = function(delta) { - var row = delta.start.row; - if (row == delta.end.row) highlight.cache[row] = undefined; - else highlight.cache.splice(row, highlight.cache.length); - }; - highlight.session.on("changeEditor", highlight.destroy); - highlight.session.on("change", highlight.updateOnChange); - } - var re = new RegExp(o.query.source, "gmi"); - this.$searchHighlight = o.highlight = highlight; - this.$searchHighlight.setRegexp(re); - this.ace.renderer.updateBackMarkers(); - }; - this.removeOverlay = function(o) { - if (this.$searchHighlight && this.$searchHighlight.session) { - this.$searchHighlight.destroy(); - } - }; - this.getScrollInfo = function() { - var renderer = this.ace.renderer; - var config = renderer.layerConfig; - return { - left: renderer.scrollLeft, - top: renderer.scrollTop, - height: config.maxHeight, - width: config.width, - clientHeight: config.height, - clientWidth: config.width - }; - }; - this.getValue = function() { - return this.ace.getValue(); - }; - this.setValue = function(v) { - return this.ace.setValue(v); - }; - this.getTokenTypeAt = function(pos) { - var token = this.ace.session.getTokenAt(pos.line, pos.ch); - return token && /comment|string/.test(token.type) ? "string" : ""; - }; - this.findMatchingBracket = function(pos) { - var m = this.ace.session.findMatchingBracket(toAcePos(pos)); - return {to: m && toCmPos(m)}; - }; - this.indentLine = function(line, method) { - if (method === true) - this.ace.session.indentRows(line, line, "\t"); - else if (method === false) - this.ace.session.outdentRows(new Range(line, 0, line, 0)); - }; - this.indexFromPos = function(pos) { - return this.ace.session.doc.positionToIndex(toAcePos(pos)); - }; - this.posFromIndex = function(index) { - return toCmPos(this.ace.session.doc.indexToPosition(index)); - }; - this.focus = function(index) { - return this.ace.textInput.focus(); - }; - this.blur = function(index) { - return this.ace.blur(); - }; - this.defaultTextHeight = function(index) { - return this.ace.renderer.layerConfig.lineHeight; - }; - this.scanForBracket = function(pos, dir, _, options) { - var re = options.bracketRegex.source; - if (dir == 1) { - var m = this.ace.session.$findClosingBracket(re.slice(1, 2), toAcePos(pos), /paren|text/); - } else { - var m = this.ace.session.$findOpeningBracket(re.slice(-2, -1), {row: pos.line, column: pos.ch + 1}, /paren|text/); - } - return m && {pos: toCmPos(m)}; - }; - this.refresh = function() { - return this.ace.resize(true); - }; - this.getMode = function() { - return { name : this.getOption("mode") }; - } -}).call(CodeMirror.prototype); - function toAcePos(cmPos) { - return {row: cmPos.line, column: cmPos.ch}; - } - function toCmPos(acePos) { - return new Pos(acePos.row, acePos.column); - } - - var StringStream = CodeMirror.StringStream = function(string, tabSize) { - this.pos = this.start = 0; - this.string = string; - this.tabSize = tabSize || 8; - this.lastColumnPos = this.lastColumnValue = 0; - this.lineStart = 0; - }; - - StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == this.lineStart;}, - peek: function() {return this.string.charAt(this.pos) || undefined;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() { - throw "not implemented"; - }, - indentation: function() { - throw "not implemented"; - }, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);}, - hideFirstChars: function(n, inner) { - this.lineStart += n; - try { return inner(); } - finally { this.lineStart -= n; } - } - }; - -// todo replace with showCommandLine -CodeMirror.defineExtension = function(name, fn) { - CodeMirror.prototype[name] = fn; -}; -dom.importCssString(".normal-mode .ace_cursor{\ - border: 1px solid red;\ - background-color: red;\ - opacity: 0.5;\ -}\ -.normal-mode .ace_hidden-cursors .ace_cursor{\ - background-color: transparent;\ -}\ -.ace_dialog {\ - position: absolute;\ - left: 0; right: 0;\ - background: white;\ - z-index: 15;\ - padding: .1em .8em;\ - overflow: hidden;\ - color: #333;\ -}\ -.ace_dialog-top {\ - border-bottom: 1px solid #eee;\ - top: 0;\ -}\ -.ace_dialog-bottom {\ - border-top: 1px solid #eee;\ - bottom: 0;\ -}\ -.ace_dialog input {\ - border: none;\ - outline: none;\ - background: transparent;\ - width: 20em;\ - color: inherit;\ - font-family: monospace;\ -}", "vimMode"); -(function() { - function dialogDiv(cm, template, bottom) { - var wrap = cm.ace.container; - var dialog; - dialog = wrap.appendChild(document.createElement("div")); - if (bottom) - dialog.className = "ace_dialog ace_dialog-bottom"; - else - dialog.className = "ace_dialog ace_dialog-top"; - - if (typeof template == "string") { - dialog.innerHTML = template; - } else { // Assuming it's a detached DOM element. - dialog.appendChild(template); - } - return dialog; - } - - function closeNotification(cm, newVal) { - if (cm.state.currentNotificationClose) - cm.state.currentNotificationClose(); - cm.state.currentNotificationClose = newVal; - } - - CodeMirror.defineExtension("openDialog", function(template, callback, options) { - if (this.virtualSelectionMode()) return; - if (!options) options = {}; - - closeNotification(this, null); - - var dialog = dialogDiv(this, template, options.bottom); - var closed = false, me = this; - function close(newVal) { - if (typeof newVal == 'string') { - inp.value = newVal; - } else { - if (closed) return; - closed = true; - dialog.parentNode.removeChild(dialog); - me.focus(); - - if (options.onClose) options.onClose(dialog); - } - } - - var inp = dialog.getElementsByTagName("input")[0], button; - if (inp) { - if (options.value) { - inp.value = options.value; - if (options.selectValueOnOpen !== false) inp.select(); - } - - if (options.onInput) - CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);}); - if (options.onKeyUp) - CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); - - CodeMirror.on(inp, "keydown", function(e) { - if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } - if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { - inp.blur(); - CodeMirror.e_stop(e); - close(); - } - if (e.keyCode == 13) callback(inp.value); - }); - - if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); - - inp.focus(); - } else if (button = dialog.getElementsByTagName("button")[0]) { - CodeMirror.on(button, "click", function() { - close(); - me.focus(); - }); - - if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close); - - button.focus(); - } - return close; - }); - - CodeMirror.defineExtension("openNotification", function(template, options) { - if (this.virtualSelectionMode()) return; - closeNotification(this, close); - var dialog = dialogDiv(this, template, options && options.bottom); - var closed = false, doneTimer; - var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; - - function close() { - if (closed) return; - closed = true; - clearTimeout(doneTimer); - dialog.parentNode.removeChild(dialog); - } - - CodeMirror.on(dialog, 'click', function(e) { - CodeMirror.e_preventDefault(e); - close(); - }); - - if (duration) - doneTimer = setTimeout(close, duration); - - return close; - }); -})(); - - - var defaultKeymap = [ - // Key to key mapping. This goes first to make it possible to override - // existing mappings. - { keys: '', type: 'keyToKey', toKeys: 'h' }, - { keys: '', type: 'keyToKey', toKeys: 'l' }, - { keys: '', type: 'keyToKey', toKeys: 'k' }, - { keys: '', type: 'keyToKey', toKeys: 'j' }, - { keys: '', type: 'keyToKey', toKeys: 'l' }, - { keys: '', type: 'keyToKey', toKeys: 'h', context: 'normal'}, - { keys: '', type: 'keyToKey', toKeys: 'W' }, - { keys: '', type: 'keyToKey', toKeys: 'B', context: 'normal' }, - { keys: '', type: 'keyToKey', toKeys: 'w' }, - { keys: '', type: 'keyToKey', toKeys: 'b', context: 'normal' }, - { keys: '', type: 'keyToKey', toKeys: 'j' }, - { keys: '', type: 'keyToKey', toKeys: 'k' }, - { keys: '', type: 'keyToKey', toKeys: '' }, - { keys: '', type: 'keyToKey', toKeys: '' }, - { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, - { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, - { keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' }, - { keys: 's', type: 'keyToKey', toKeys: 'c', context: 'visual'}, - { keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' }, - { keys: 'S', type: 'keyToKey', toKeys: 'VdO', context: 'visual' }, - { keys: '', type: 'keyToKey', toKeys: '0' }, - { keys: '', type: 'keyToKey', toKeys: '$' }, - { keys: '', type: 'keyToKey', toKeys: '' }, - { keys: '', type: 'keyToKey', toKeys: '' }, - { keys: '', type: 'keyToKey', toKeys: 'j^', context: 'normal' }, - { keys: '', type: 'action', action: 'toggleOverwrite', context: 'insert' }, - // Motions - { keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }}, - { keys: 'M', type: 'motion', motion: 'moveToMiddleLine', motionArgs: { linewise: true, toJumplist: true }}, - { keys: 'L', type: 'motion', motion: 'moveToBottomLine', motionArgs: { linewise: true, toJumplist: true }}, - { keys: 'h', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: false }}, - { keys: 'l', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: true }}, - { keys: 'j', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, linewise: true }}, - { keys: 'k', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, linewise: true }}, - { keys: 'gj', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: true }}, - { keys: 'gk', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: false }}, - { keys: 'w', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false }}, - { keys: 'W', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false, bigWord: true }}, - { keys: 'e', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, inclusive: true }}, - { keys: 'E', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, bigWord: true, inclusive: true }}, - { keys: 'b', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }}, - { keys: 'B', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false, bigWord: true }}, - { keys: 'ge', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, inclusive: true }}, - { keys: 'gE', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, bigWord: true, inclusive: true }}, - { keys: '{', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: false, toJumplist: true }}, - { keys: '}', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: true, toJumplist: true }}, - { keys: '', type: 'motion', motion: 'moveByPage', motionArgs: { forward: true }}, - { keys: '', type: 'motion', motion: 'moveByPage', motionArgs: { forward: false }}, - { keys: '', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: true, explicitRepeat: true }}, - { keys: '', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }}, - { keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }}, - { keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }}, - { keys: '0', type: 'motion', motion: 'moveToStartOfLine' }, - { keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' }, - { keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }}, - { keys: '-', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, toFirstChar:true }}, - { keys: '_', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true, repeatOffset:-1 }}, - { keys: '$', type: 'motion', motion: 'moveToEol', motionArgs: { inclusive: true }}, - { keys: '%', type: 'motion', motion: 'moveToMatchedSymbol', motionArgs: { inclusive: true, toJumplist: true }}, - { keys: 'f', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: true , inclusive: true }}, - { keys: 'F', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: false }}, - { keys: 't', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: true, inclusive: true }}, - { keys: 'T', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: false }}, - { keys: ';', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: true }}, - { keys: ',', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: false }}, - { keys: '\'', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true, linewise: true}}, - { keys: '`', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true}}, - { keys: ']`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true } }, - { keys: '[`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false } }, - { keys: ']\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true, linewise: true } }, - { keys: '[\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false, linewise: true } }, - // the next two aren't motions but must come before more general motion declarations - { keys: ']p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true, matchIndent: true}}, - { keys: '[p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true, matchIndent: true}}, - { keys: ']', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: true, toJumplist: true}}, - { keys: '[', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: false, toJumplist: true}}, - { keys: '|', type: 'motion', motion: 'moveToColumn'}, - { keys: 'o', type: 'motion', motion: 'moveToOtherHighlightedEnd', context:'visual'}, - { keys: 'O', type: 'motion', motion: 'moveToOtherHighlightedEnd', motionArgs: {sameLine: true}, context:'visual'}, - // Operators - { keys: 'd', type: 'operator', operator: 'delete' }, - { keys: 'y', type: 'operator', operator: 'yank' }, - { keys: 'c', type: 'operator', operator: 'change' }, - { keys: '>', type: 'operator', operator: 'indent', operatorArgs: { indentRight: true }}, - { keys: '<', type: 'operator', operator: 'indent', operatorArgs: { indentRight: false }}, - { keys: 'g~', type: 'operator', operator: 'changeCase' }, - { keys: 'gu', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, isEdit: true }, - { keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true }, - { keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }}, - { keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }}, - // Operator-Motion dual commands - { keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }}, - { keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }}, - { keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, - { keys: 'D', type: 'operator', operator: 'delete', operatorArgs: { linewise: true }, context: 'visual'}, - { keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, - { keys: 'Y', type: 'operator', operator: 'yank', operatorArgs: { linewise: true }, context: 'visual'}, - { keys: 'C', type: 'operatorMotion', operator: 'change', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, - { keys: 'C', type: 'operator', operator: 'change', operatorArgs: { linewise: true }, context: 'visual'}, - { keys: '~', type: 'operatorMotion', operator: 'changeCase', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorArgs: { shouldMoveCursor: true }, context: 'normal'}, - { keys: '~', type: 'operator', operator: 'changeCase', context: 'visual'}, - { keys: '', type: 'operatorMotion', operator: 'delete', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }, context: 'insert' }, - // Actions - { keys: '', type: 'action', action: 'jumpListWalk', actionArgs: { forward: true }}, - { keys: '', type: 'action', action: 'jumpListWalk', actionArgs: { forward: false }}, - { keys: '', type: 'action', action: 'scroll', actionArgs: { forward: true, linewise: true }}, - { keys: '', type: 'action', action: 'scroll', actionArgs: { forward: false, linewise: true }}, - { keys: 'a', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'charAfter' }, context: 'normal' }, - { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' }, - { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' }, - { keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' }, - { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' }, - { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' }, - { keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' }, - { keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' }, - { keys: 'v', type: 'action', action: 'toggleVisualMode' }, - { keys: 'V', type: 'action', action: 'toggleVisualMode', actionArgs: { linewise: true }}, - { keys: '', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }}, - { keys: '', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }}, - { keys: 'gv', type: 'action', action: 'reselectLastSelection' }, - { keys: 'J', type: 'action', action: 'joinLines', isEdit: true }, - { keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }}, - { keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }}, - { keys: 'r', type: 'action', action: 'replace', isEdit: true }, - { keys: '@', type: 'action', action: 'replayMacro' }, - { keys: 'q', type: 'action', action: 'enterMacroRecordMode' }, - // Handle Replace-mode as a special case of insert mode. - { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }}, - { keys: 'u', type: 'action', action: 'undo', context: 'normal' }, - { keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true }, - { keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true }, - { keys: '', type: 'action', action: 'redo' }, - { keys: 'm', type: 'action', action: 'setMark' }, - { keys: '"', type: 'action', action: 'setRegister' }, - { keys: 'zz', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }}, - { keys: 'z.', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, - { keys: 'zt', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }}, - { keys: 'z', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, - { keys: 'z-', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }}, - { keys: 'zb', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, - { keys: '.', type: 'action', action: 'repeatLastEdit' }, - { keys: '', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: true, backtrack: false}}, - { keys: '', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: false, backtrack: false}}, - { keys: '', type: 'action', action: 'indent', actionArgs: { indentRight: true }, context: 'insert' }, - { keys: '', type: 'action', action: 'indent', actionArgs: { indentRight: false }, context: 'insert' }, - // Text object motions - { keys: 'a', type: 'motion', motion: 'textObjectManipulation' }, - { keys: 'i', type: 'motion', motion: 'textObjectManipulation', motionArgs: { textObjectInner: true }}, - // Search - { keys: '/', type: 'search', searchArgs: { forward: true, querySrc: 'prompt', toJumplist: true }}, - { keys: '?', type: 'search', searchArgs: { forward: false, querySrc: 'prompt', toJumplist: true }}, - { keys: '*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }}, - { keys: '#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }}, - { keys: 'g*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', toJumplist: true }}, - { keys: 'g#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', toJumplist: true }}, - // Ex command - { keys: ':', type: 'ex' } - ]; - - /** - * Ex commands - * Care must be taken when adding to the default Ex command map. For any - * pair of commands that have a shared prefix, at least one of their - * shortNames must not match the prefix of the other command. - */ - var defaultExCommandMap = [ - { name: 'colorscheme', shortName: 'colo' }, - { name: 'map' }, - { name: 'imap', shortName: 'im' }, - { name: 'nmap', shortName: 'nm' }, - { name: 'vmap', shortName: 'vm' }, - { name: 'unmap' }, - { name: 'write', shortName: 'w' }, - { name: 'undo', shortName: 'u' }, - { name: 'redo', shortName: 'red' }, - { name: 'set', shortName: 'se' }, - { name: 'set', shortName: 'se' }, - { name: 'setlocal', shortName: 'setl' }, - { name: 'setglobal', shortName: 'setg' }, - { name: 'sort', shortName: 'sor' }, - { name: 'substitute', shortName: 's', possiblyAsync: true }, - { name: 'nohlsearch', shortName: 'noh' }, - { name: 'yank', shortName: 'y' }, - { name: 'delmarks', shortName: 'delm' }, - { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true }, - { name: 'global', shortName: 'g' } - ]; - - var Pos = CodeMirror.Pos; - - var Vim = function() { return vimApi; } //{ - function enterVimMode(cm) { - cm.setOption('disableInput', true); - cm.setOption('showCursorWhenSelecting', false); - CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); - cm.on('cursorActivity', onCursorActivity); - maybeInitVimState(cm); - CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm)); - } - - function leaveVimMode(cm) { - cm.setOption('disableInput', false); - cm.off('cursorActivity', onCursorActivity); - CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm)); - cm.state.vim = null; - } - - function detachVimMap(cm, next) { - if (this == CodeMirror.keyMap.vim) - CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor"); - - if (!next || next.attach != attachVimMap) - leaveVimMode(cm); - } - function attachVimMap(cm, prev) { - if (this == CodeMirror.keyMap.vim) - CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor"); - - if (!prev || prev.attach != attachVimMap) - enterVimMode(cm); - } - - // Deprecated, simply setting the keymap works again. - CodeMirror.defineOption('vimMode', false, function(cm, val, prev) { - if (val && cm.getOption("keyMap") != "vim") - cm.setOption("keyMap", "vim"); - else if (!val && prev != CodeMirror.Init && /^vim/.test(cm.getOption("keyMap"))) - cm.setOption("keyMap", "default"); - }); - - function cmKey(key, cm) { - if (!cm) { return undefined; } - if (this[key]) { return this[key]; } - var vimKey = cmKeyToVimKey(key); - if (!vimKey) { - return false; - } - var cmd = CodeMirror.Vim.findKey(cm, vimKey); - if (typeof cmd == 'function') { - CodeMirror.signal(cm, 'vim-keypress', vimKey); - } - return cmd; - } - - var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'}; - var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del',Insert:'Ins'}; - function cmKeyToVimKey(key) { - if (key.charAt(0) == '\'') { - // Keypress character binding of format "'a'" - return key.charAt(1); - } - var pieces = key.split(/-(?!$)/); - var lastPiece = pieces[pieces.length - 1]; - if (pieces.length == 1 && pieces[0].length == 1) { - // No-modifier bindings use literal character bindings above. Skip. - return false; - } else if (pieces.length == 2 && pieces[0] == 'Shift' && lastPiece.length == 1) { - // Ignore Shift+char bindings as they should be handled by literal character. - return false; - } - var hasCharacter = false; - for (var i = 0; i < pieces.length; i++) { - var piece = pieces[i]; - if (piece in modifiers) { pieces[i] = modifiers[piece]; } - else { hasCharacter = true; } - if (piece in specialKeys) { pieces[i] = specialKeys[piece]; } - } - if (!hasCharacter) { - // Vim does not support modifier only keys. - return false; - } - // TODO: Current bindings expect the character to be lower case, but - // it looks like vim key notation uses upper case. - if (isUpperCase(lastPiece)) { - pieces[pieces.length - 1] = lastPiece.toLowerCase(); - } - return '<' + pieces.join('-') + '>'; - } - - function getOnPasteFn(cm) { - var vim = cm.state.vim; - if (!vim.onPasteFn) { - vim.onPasteFn = function() { - if (!vim.insertMode) { - cm.setCursor(offsetCursor(cm.getCursor(), 0, 1)); - actions.enterInsertMode(cm, {}, vim); - } - }; - } - return vim.onPasteFn; - } - - var numberRegex = /[\d]/; - var wordCharTest = [CodeMirror.isWordChar, function(ch) { - return ch && !CodeMirror.isWordChar(ch) && !/\s/.test(ch); - }], bigWordCharTest = [function(ch) { - return /\S/.test(ch); - }]; - function makeKeyRange(start, size) { - var keys = []; - for (var i = start; i < start + size; i++) { - keys.push(String.fromCharCode(i)); - } - return keys; - } - var upperCaseAlphabet = makeKeyRange(65, 26); - var lowerCaseAlphabet = makeKeyRange(97, 26); - var numbers = makeKeyRange(48, 10); - var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']); - var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '/']); - - function isLine(cm, line) { - return line >= cm.firstLine() && line <= cm.lastLine(); - } - function isLowerCase(k) { - return (/^[a-z]$/).test(k); - } - function isMatchableSymbol(k) { - return '()[]{}'.indexOf(k) != -1; - } - function isNumber(k) { - return numberRegex.test(k); - } - function isUpperCase(k) { - return (/^[A-Z]$/).test(k); - } - function isWhiteSpaceString(k) { - return (/^\s*$/).test(k); - } - function inArray(val, arr) { - for (var i = 0; i < arr.length; i++) { - if (arr[i] == val) { - return true; - } - } - return false; - } - - var options = {}; - function defineOption(name, defaultValue, type, aliases, callback) { - if (defaultValue === undefined && !callback) { - throw Error('defaultValue is required unless callback is provided'); - } - if (!type) { type = 'string'; } - options[name] = { - type: type, - defaultValue: defaultValue, - callback: callback - }; - if (aliases) { - for (var i = 0; i < aliases.length; i++) { - options[aliases[i]] = options[name]; - } - } - if (defaultValue) { - setOption(name, defaultValue); - } - } - - function setOption(name, value, cm, cfg) { - var option = options[name]; - cfg = cfg || {}; - var scope = cfg.scope; - if (!option) { - return new Error('Unknown option: ' + name); - } - if (option.type == 'boolean') { - if (value && value !== true) { - return new Error('Invalid argument: ' + name + '=' + value); - } else if (value !== false) { - // Boolean options are set to true if value is not defined. - value = true; - } - } - if (option.callback) { - if (scope !== 'local') { - option.callback(value, undefined); - } - if (scope !== 'global' && cm) { - option.callback(value, cm); - } - } else { - if (scope !== 'local') { - option.value = option.type == 'boolean' ? !!value : value; - } - if (scope !== 'global' && cm) { - cm.state.vim.options[name] = {value: value}; - } - } - } - - function getOption(name, cm, cfg) { - var option = options[name]; - cfg = cfg || {}; - var scope = cfg.scope; - if (!option) { - return new Error('Unknown option: ' + name); - } - if (option.callback) { - var local = cm && option.callback(undefined, cm); - if (scope !== 'global' && local !== undefined) { - return local; - } - if (scope !== 'local') { - return option.callback(); - } - return; - } else { - var local = (scope !== 'global') && (cm && cm.state.vim.options[name]); - return (local || (scope !== 'local') && option || {}).value; - } - } - - defineOption('filetype', undefined, 'string', ['ft'], function(name, cm) { - // Option is local. Do nothing for global. - if (cm === undefined) { - return; - } - // The 'filetype' option proxies to the CodeMirror 'mode' option. - if (name === undefined) { - var mode = cm.getOption('mode'); - return mode == 'null' ? '' : mode; - } else { - var mode = name == '' ? 'null' : name; - cm.setOption('mode', mode); - } - }); - - var createCircularJumpList = function() { - var size = 100; - var pointer = -1; - var head = 0; - var tail = 0; - var buffer = new Array(size); - function add(cm, oldCur, newCur) { - var current = pointer % size; - var curMark = buffer[current]; - function useNextSlot(cursor) { - var next = ++pointer % size; - var trashMark = buffer[next]; - if (trashMark) { - trashMark.clear(); - } - buffer[next] = cm.setBookmark(cursor); - } - if (curMark) { - var markPos = curMark.find(); - // avoid recording redundant cursor position - if (markPos && !cursorEqual(markPos, oldCur)) { - useNextSlot(oldCur); - } - } else { - useNextSlot(oldCur); - } - useNextSlot(newCur); - head = pointer; - tail = pointer - size + 1; - if (tail < 0) { - tail = 0; - } - } - function move(cm, offset) { - pointer += offset; - if (pointer > head) { - pointer = head; - } else if (pointer < tail) { - pointer = tail; - } - var mark = buffer[(size + pointer) % size]; - // skip marks that are temporarily removed from text buffer - if (mark && !mark.find()) { - var inc = offset > 0 ? 1 : -1; - var newCur; - var oldCur = cm.getCursor(); - do { - pointer += inc; - mark = buffer[(size + pointer) % size]; - // skip marks that are the same as current position - if (mark && - (newCur = mark.find()) && - !cursorEqual(oldCur, newCur)) { - break; - } - } while (pointer < head && pointer > tail); - } - return mark; - } - return { - cachedCursor: undefined, //used for # and * jumps - add: add, - move: move - }; - }; - - // Returns an object to track the changes associated insert mode. It - // clones the object that is passed in, or creates an empty object one if - // none is provided. - var createInsertModeChanges = function(c) { - if (c) { - // Copy construction - return { - changes: c.changes, - expectCursorActivityForChange: c.expectCursorActivityForChange - }; - } - return { - // Change list - changes: [], - // Set to true on change, false on cursorActivity. - expectCursorActivityForChange: false - }; - }; - - function MacroModeState() { - this.latestRegister = undefined; - this.isPlaying = false; - this.isRecording = false; - this.replaySearchQueries = []; - this.onRecordingDone = undefined; - this.lastInsertModeChanges = createInsertModeChanges(); - } - MacroModeState.prototype = { - exitMacroRecordMode: function() { - var macroModeState = vimGlobalState.macroModeState; - if (macroModeState.onRecordingDone) { - macroModeState.onRecordingDone(); // close dialog - } - macroModeState.onRecordingDone = undefined; - macroModeState.isRecording = false; - }, - enterMacroRecordMode: function(cm, registerName) { - var register = - vimGlobalState.registerController.getRegister(registerName); - if (register) { - register.clear(); - this.latestRegister = registerName; - if (cm.openDialog) { - this.onRecordingDone = cm.openDialog( - '(recording)['+registerName+']', null, {bottom:true}); - } - this.isRecording = true; - } - } - }; - - function maybeInitVimState(cm) { - if (!cm.state.vim) { - // Store instance state in the CodeMirror object. - cm.state.vim = { - inputState: new InputState(), - // Vim's input state that triggered the last edit, used to repeat - // motions and operators with '.'. - lastEditInputState: undefined, - // Vim's action command before the last edit, used to repeat actions - // with '.' and insert mode repeat. - lastEditActionCommand: undefined, - // When using jk for navigation, if you move from a longer line to a - // shorter line, the cursor may clip to the end of the shorter line. - // If j is pressed again and cursor goes to the next line, the - // cursor should go back to its horizontal position on the longer - // line if it can. This is to keep track of the horizontal position. - lastHPos: -1, - // Doing the same with screen-position for gj/gk - lastHSPos: -1, - // The last motion command run. Cleared if a non-motion command gets - // executed in between. - lastMotion: null, - marks: {}, - // Mark for rendering fake cursor for visual mode. - fakeCursor: null, - insertMode: false, - // Repeat count for changes made in insert mode, triggered by key - // sequences like 3,i. Only exists when insertMode is true. - insertModeRepeat: undefined, - visualMode: false, - // If we are in visual line mode. No effect if visualMode is false. - visualLine: false, - visualBlock: false, - lastSelection: null, - lastPastedText: null, - sel: {}, - // Buffer-local/window-local values of vim options. - options: {} - }; - } - return cm.state.vim; - } - var vimGlobalState; - function resetVimGlobalState() { - vimGlobalState = { - // The current search query. - searchQuery: null, - // Whether we are searching backwards. - searchIsReversed: false, - // Replace part of the last substituted pattern - lastSubstituteReplacePart: undefined, - jumpList: createCircularJumpList(), - macroModeState: new MacroModeState, - // Recording latest f, t, F or T motion command. - lastCharacterSearch: {increment:0, forward:true, selectedCharacter:''}, - registerController: new RegisterController({}), - // search history buffer - searchHistoryController: new HistoryController(), - // ex Command history buffer - exCommandHistoryController : new HistoryController() - }; - for (var optionName in options) { - var option = options[optionName]; - option.value = option.defaultValue; - } - } - - var lastInsertModeKeyTimer; - var vimApi= { - buildKeyMap: function() { - // TODO: Convert keymap into dictionary format for fast lookup. - }, - // Testing hook, though it might be useful to expose the register - // controller anyways. - getRegisterController: function() { - return vimGlobalState.registerController; - }, - // Testing hook. - resetVimGlobalState_: resetVimGlobalState, - - // Testing hook. - getVimGlobalState_: function() { - return vimGlobalState; - }, - - // Testing hook. - maybeInitVimState_: maybeInitVimState, - - suppressErrorLogging: false, - - InsertModeKey: InsertModeKey, - map: function(lhs, rhs, ctx) { - // Add user defined key bindings. - exCommandDispatcher.map(lhs, rhs, ctx); - }, - unmap: function(lhs, ctx) { - exCommandDispatcher.unmap(lhs, ctx); - }, - // TODO: Expose setOption and getOption as instance methods. Need to decide how to namespace - // them, or somehow make them work with the existing CodeMirror setOption/getOption API. - setOption: setOption, - getOption: getOption, - defineOption: defineOption, - defineEx: function(name, prefix, func){ - if (!prefix) { - prefix = name; - } else if (name.indexOf(prefix) !== 0) { - throw new Error('(Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", command not registered'); - } - exCommands[name]=func; - exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'}; - }, - handleKey: function (cm, key, origin) { - var command = this.findKey(cm, key, origin); - if (typeof command === 'function') { - return command(); - } - }, - /** - * This is the outermost function called by CodeMirror, after keys have - * been mapped to their Vim equivalents. - * - * Finds a command based on the key (and cached keys if there is a - * multi-key sequence). Returns `undefined` if no key is matched, a noop - * function if a partial match is found (multi-key), and a function to - * execute the bound command if a a key is matched. The function always - * returns true. - */ - findKey: function(cm, key, origin) { - var vim = maybeInitVimState(cm); - function handleMacroRecording() { - var macroModeState = vimGlobalState.macroModeState; - if (macroModeState.isRecording) { - if (key == 'q') { - macroModeState.exitMacroRecordMode(); - clearInputState(cm); - return true; - } - if (origin != 'mapping') { - logKey(macroModeState, key); - } - } - } - function handleEsc() { - if (key == '') { - // Clear input state and get back to normal mode. - clearInputState(cm); - if (vim.visualMode) { - exitVisualMode(cm); - } else if (vim.insertMode) { - exitInsertMode(cm); - } - return true; - } - } - function doKeyToKey(keys) { - // TODO: prevent infinite recursion. - var match; - while (keys) { - // Pull off one command key, which is either a single character - // or a special sequence wrapped in '<' and '>', e.g. ''. - match = (/<\w+-.+?>|<\w+>|./).exec(keys); - key = match[0]; - keys = keys.substring(match.index + key.length); - CodeMirror.Vim.handleKey(cm, key, 'mapping'); - } - } - - function handleKeyInsertMode() { - if (handleEsc()) { return true; } - var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key; - var keysAreChars = key.length == 1; - var match = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert'); - // Need to check all key substrings in insert mode. - while (keys.length > 1 && match.type != 'full') { - var keys = vim.inputState.keyBuffer = keys.slice(1); - var thisMatch = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert'); - if (thisMatch.type != 'none') { match = thisMatch; } - } - if (match.type == 'none') { clearInputState(cm); return false; } - else if (match.type == 'partial') { - if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); } - lastInsertModeKeyTimer = window.setTimeout( - function() { if (vim.insertMode && vim.inputState.keyBuffer) { clearInputState(cm); } }, - getOption('insertModeEscKeysTimeout')); - return !keysAreChars; - } - - if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); } - if (keysAreChars) { - var selections = cm.listSelections(); - for (var i = 0; i < selections.length; i++) { - var here = selections[i].head; - cm.replaceRange('', offsetCursor(here, 0, -(keys.length - 1)), here, '+input'); - } - vimGlobalState.macroModeState.lastInsertModeChanges.changes.pop(); - } - clearInputState(cm); - return match.command; - } - - function handleKeyNonInsertMode() { - if (handleMacroRecording() || handleEsc()) { return true; } - - var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key; - if (/^[1-9]\d*$/.test(keys)) { return true; } - - var keysMatcher = /^(\d*)(.*)$/.exec(keys); - if (!keysMatcher) { clearInputState(cm); return false; } - var context = vim.visualMode ? 'visual' : - 'normal'; - var match = commandDispatcher.matchCommand(keysMatcher[2] || keysMatcher[1], defaultKeymap, vim.inputState, context); - if (match.type == 'none') { clearInputState(cm); return false; } - else if (match.type == 'partial') { return true; } - - vim.inputState.keyBuffer = ''; - var keysMatcher = /^(\d*)(.*)$/.exec(keys); - if (keysMatcher[1] && keysMatcher[1] != '0') { - vim.inputState.pushRepeatDigit(keysMatcher[1]); - } - return match.command; - } - - var command; - if (vim.insertMode) { command = handleKeyInsertMode(); } - else { command = handleKeyNonInsertMode(); } - if (command === false) { - return undefined; - } else if (command === true) { - // TODO: Look into using CodeMirror's multi-key handling. - // Return no-op since we are caching the key. Counts as handled, but - // don't want act on it just yet. - return function() { return true; }; - } else { - return function() { - if ((command.operator || command.isEdit) && cm.getOption('readOnly')) - return; // ace_patch - return cm.operation(function() { - cm.curOp.isVimOp = true; - try { - if (command.type == 'keyToKey') { - doKeyToKey(command.toKeys); - } else { - commandDispatcher.processCommand(cm, vim, command); - } - } catch (e) { - // clear VIM state in case it's in a bad state. - cm.state.vim = undefined; - maybeInitVimState(cm); - if (!CodeMirror.Vim.suppressErrorLogging) { - console['log'](e); - } - throw e; - } - return true; - }); - }; - } - }, - handleEx: function(cm, input) { - exCommandDispatcher.processCommand(cm, input); - }, - - defineMotion: defineMotion, - defineAction: defineAction, - defineOperator: defineOperator, - mapCommand: mapCommand, - _mapCommand: _mapCommand, - - defineRegister: defineRegister, - - exitVisualMode: exitVisualMode, - exitInsertMode: exitInsertMode - }; - - // Represents the current input state. - function InputState() { - this.prefixRepeat = []; - this.motionRepeat = []; - - this.operator = null; - this.operatorArgs = null; - this.motion = null; - this.motionArgs = null; - this.keyBuffer = []; // For matching multi-key commands. - this.registerName = null; // Defaults to the unnamed register. - } - InputState.prototype.pushRepeatDigit = function(n) { - if (!this.operator) { - this.prefixRepeat = this.prefixRepeat.concat(n); - } else { - this.motionRepeat = this.motionRepeat.concat(n); - } - }; - InputState.prototype.getRepeat = function() { - var repeat = 0; - if (this.prefixRepeat.length > 0 || this.motionRepeat.length > 0) { - repeat = 1; - if (this.prefixRepeat.length > 0) { - repeat *= parseInt(this.prefixRepeat.join(''), 10); - } - if (this.motionRepeat.length > 0) { - repeat *= parseInt(this.motionRepeat.join(''), 10); - } - } - return repeat; - }; - - function clearInputState(cm, reason) { - cm.state.vim.inputState = new InputState(); - CodeMirror.signal(cm, 'vim-command-done', reason); - } - - /* - * Register stores information about copy and paste registers. Besides - * text, a register must store whether it is linewise (i.e., when it is - * pasted, should it insert itself into a new line, or should the text be - * inserted at the cursor position.) - */ - function Register(text, linewise, blockwise) { - this.clear(); - this.keyBuffer = [text || '']; - this.insertModeChanges = []; - this.searchQueries = []; - this.linewise = !!linewise; - this.blockwise = !!blockwise; - } - Register.prototype = { - setText: function(text, linewise, blockwise) { - this.keyBuffer = [text || '']; - this.linewise = !!linewise; - this.blockwise = !!blockwise; - }, - pushText: function(text, linewise) { - // if this register has ever been set to linewise, use linewise. - if (linewise) { - if (!this.linewise) { - this.keyBuffer.push('\n'); - } - this.linewise = true; - } - this.keyBuffer.push(text); - }, - pushInsertModeChanges: function(changes) { - this.insertModeChanges.push(createInsertModeChanges(changes)); - }, - pushSearchQuery: function(query) { - this.searchQueries.push(query); - }, - clear: function() { - this.keyBuffer = []; - this.insertModeChanges = []; - this.searchQueries = []; - this.linewise = false; - }, - toString: function() { - return this.keyBuffer.join(''); - } - }; - - /** - * Defines an external register. - * - * The name should be a single character that will be used to reference the register. - * The register should support setText, pushText, clear, and toString(). See Register - * for a reference implementation. - */ - function defineRegister(name, register) { - var registers = vimGlobalState.registerController.registers; - if (!name || name.length != 1) { - throw Error('Register name must be 1 character'); - } - // ace_patch - registers[name] = register; - validRegisters.push(name); - } - - /* - * vim registers allow you to keep many independent copy and paste buffers. - * See http://usevim.com/2012/04/13/registers/ for an introduction. - * - * RegisterController keeps the state of all the registers. An initial - * state may be passed in. The unnamed register '"' will always be - * overridden. - */ - function RegisterController(registers) { - this.registers = registers; - this.unnamedRegister = registers['"'] = new Register(); - registers['.'] = new Register(); - registers[':'] = new Register(); - registers['/'] = new Register(); - } - RegisterController.prototype = { - pushText: function(registerName, operator, text, linewise, blockwise) { - if (linewise && text.charAt(text.length - 1) !== '\n'){ - text += '\n'; - } - // Lowercase and uppercase registers refer to the same register. - // Uppercase just means append. - var register = this.isValidRegister(registerName) ? - this.getRegister(registerName) : null; - // if no register/an invalid register was specified, things go to the - // default registers - if (!register) { - switch (operator) { - case 'yank': - // The 0 register contains the text from the most recent yank. - this.registers['0'] = new Register(text, linewise, blockwise); - break; - case 'delete': - case 'change': - if (text.indexOf('\n') == -1) { - // Delete less than 1 line. Update the small delete register. - this.registers['-'] = new Register(text, linewise); - } else { - // Shift down the contents of the numbered registers and put the - // deleted text into register 1. - this.shiftNumericRegisters_(); - this.registers['1'] = new Register(text, linewise); - } - break; - } - // Make sure the unnamed register is set to what just happened - this.unnamedRegister.setText(text, linewise, blockwise); - return; - } - - // If we've gotten to this point, we've actually specified a register - var append = isUpperCase(registerName); - if (append) { - register.pushText(text, linewise); - } else { - register.setText(text, linewise, blockwise); - } - // The unnamed register always has the same value as the last used - // register. - this.unnamedRegister.setText(register.toString(), linewise); - }, - // Gets the register named @name. If one of @name doesn't already exist, - // create it. If @name is invalid, return the unnamedRegister. - getRegister: function(name) { - if (!this.isValidRegister(name)) { - return this.unnamedRegister; - } - name = name.toLowerCase(); - if (!this.registers[name]) { - this.registers[name] = new Register(); - } - return this.registers[name]; - }, - isValidRegister: function(name) { - return name && inArray(name, validRegisters); - }, - shiftNumericRegisters_: function() { - for (var i = 9; i >= 2; i--) { - this.registers[i] = this.getRegister('' + (i - 1)); - } - } - }; - function HistoryController() { - this.historyBuffer = []; - this.iterator = 0; - this.initialPrefix = null; - } - HistoryController.prototype = { - // the input argument here acts a user entered prefix for a small time - // until we start autocompletion in which case it is the autocompleted. - nextMatch: function (input, up) { - var historyBuffer = this.historyBuffer; - var dir = up ? -1 : 1; - if (this.initialPrefix === null) this.initialPrefix = input; - for (var i = this.iterator + dir; up ? i >= 0 : i < historyBuffer.length; i+= dir) { - var element = historyBuffer[i]; - for (var j = 0; j <= element.length; j++) { - if (this.initialPrefix == element.substring(0, j)) { - this.iterator = i; - return element; - } - } - } - // should return the user input in case we reach the end of buffer. - if (i >= historyBuffer.length) { - this.iterator = historyBuffer.length; - return this.initialPrefix; - } - // return the last autocompleted query or exCommand as it is. - if (i < 0 ) return input; - }, - pushInput: function(input) { - var index = this.historyBuffer.indexOf(input); - if (index > -1) this.historyBuffer.splice(index, 1); - if (input.length) this.historyBuffer.push(input); - }, - reset: function() { - this.initialPrefix = null; - this.iterator = this.historyBuffer.length; - } - }; - var commandDispatcher = { - matchCommand: function(keys, keyMap, inputState, context) { - var matches = commandMatches(keys, keyMap, context, inputState); - if (!matches.full && !matches.partial) { - return {type: 'none'}; - } else if (!matches.full && matches.partial) { - return {type: 'partial'}; - } - - var bestMatch; - for (var i = 0; i < matches.full.length; i++) { - var match = matches.full[i]; - if (!bestMatch) { - bestMatch = match; - } - } - if (bestMatch.keys.slice(-11) == '') { - var character = lastChar(keys); - if (//.test(character)) return {type: 'none'}; - inputState.selectedCharacter = character; - } - return {type: 'full', command: bestMatch}; - }, - processCommand: function(cm, vim, command) { - vim.inputState.repeatOverride = command.repeatOverride; - switch (command.type) { - case 'motion': - this.processMotion(cm, vim, command); - break; - case 'operator': - this.processOperator(cm, vim, command); - break; - case 'operatorMotion': - this.processOperatorMotion(cm, vim, command); - break; - case 'action': - this.processAction(cm, vim, command); - break; - case 'search': - this.processSearch(cm, vim, command); - break; - case 'ex': - case 'keyToEx': - this.processEx(cm, vim, command); - break; - default: - break; - } - }, - processMotion: function(cm, vim, command) { - vim.inputState.motion = command.motion; - vim.inputState.motionArgs = copyArgs(command.motionArgs); - this.evalInput(cm, vim); - }, - processOperator: function(cm, vim, command) { - var inputState = vim.inputState; - if (inputState.operator) { - if (inputState.operator == command.operator) { - // Typing an operator twice like 'dd' makes the operator operate - // linewise - inputState.motion = 'expandToLine'; - inputState.motionArgs = { linewise: true }; - this.evalInput(cm, vim); - return; - } else { - // 2 different operators in a row doesn't make sense. - clearInputState(cm); - } - } - inputState.operator = command.operator; - inputState.operatorArgs = copyArgs(command.operatorArgs); - if (vim.visualMode) { - // Operating on a selection in visual mode. We don't need a motion. - this.evalInput(cm, vim); - } - }, - processOperatorMotion: function(cm, vim, command) { - var visualMode = vim.visualMode; - var operatorMotionArgs = copyArgs(command.operatorMotionArgs); - if (operatorMotionArgs) { - // Operator motions may have special behavior in visual mode. - if (visualMode && operatorMotionArgs.visualLine) { - vim.visualLine = true; - } - } - this.processOperator(cm, vim, command); - if (!visualMode) { - this.processMotion(cm, vim, command); - } - }, - processAction: function(cm, vim, command) { - var inputState = vim.inputState; - var repeat = inputState.getRepeat(); - var repeatIsExplicit = !!repeat; - var actionArgs = copyArgs(command.actionArgs) || {}; - if (inputState.selectedCharacter) { - actionArgs.selectedCharacter = inputState.selectedCharacter; - } - // Actions may or may not have motions and operators. Do these first. - if (command.operator) { - this.processOperator(cm, vim, command); - } - if (command.motion) { - this.processMotion(cm, vim, command); - } - if (command.motion || command.operator) { - this.evalInput(cm, vim); - } - actionArgs.repeat = repeat || 1; - actionArgs.repeatIsExplicit = repeatIsExplicit; - actionArgs.registerName = inputState.registerName; - clearInputState(cm); - vim.lastMotion = null; - if (command.isEdit) { - this.recordLastEdit(vim, inputState, command); - } - actions[command.action](cm, actionArgs, vim); - }, - processSearch: function(cm, vim, command) { - if (!cm.getSearchCursor) { - // Search depends on SearchCursor. - return; - } - var forward = command.searchArgs.forward; - var wholeWordOnly = command.searchArgs.wholeWordOnly; - getSearchState(cm).setReversed(!forward); - var promptPrefix = (forward) ? '/' : '?'; - var originalQuery = getSearchState(cm).getQuery(); - var originalScrollPos = cm.getScrollInfo(); - function handleQuery(query, ignoreCase, smartCase) { - vimGlobalState.searchHistoryController.pushInput(query); - vimGlobalState.searchHistoryController.reset(); - try { - updateSearchQuery(cm, query, ignoreCase, smartCase); - } catch (e) { - showConfirm(cm, 'Invalid regex: ' + query); - clearInputState(cm); - return; - } - commandDispatcher.processMotion(cm, vim, { - type: 'motion', - motion: 'findNext', - motionArgs: { forward: true, toJumplist: command.searchArgs.toJumplist } - }); - } - function onPromptClose(query) { - cm.scrollTo(originalScrollPos.left, originalScrollPos.top); - handleQuery(query, true /** ignoreCase */, true /** smartCase */); - var macroModeState = vimGlobalState.macroModeState; - if (macroModeState.isRecording) { - logSearchQuery(macroModeState, query); - } - } - function onPromptKeyUp(e, query, close) { - var keyName = CodeMirror.keyName(e), up, offset; - if (keyName == 'Up' || keyName == 'Down') { - up = keyName == 'Up' ? true : false; - offset = e.target ? e.target.selectionEnd : 0; - query = vimGlobalState.searchHistoryController.nextMatch(query, up) || ''; - close(query); - if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length); - } else { - if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift') - vimGlobalState.searchHistoryController.reset(); - } - var parsedQuery; - try { - parsedQuery = updateSearchQuery(cm, query, - true /** ignoreCase */, true /** smartCase */); - } catch (e) { - // Swallow bad regexes for incremental search. - } - if (parsedQuery) { - cm.scrollIntoView(findNext(cm, !forward, parsedQuery), 30); - } else { - clearSearchHighlight(cm); - cm.scrollTo(originalScrollPos.left, originalScrollPos.top); - } - } - function onPromptKeyDown(e, query, close) { - var keyName = CodeMirror.keyName(e); - if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' || - (keyName == 'Backspace' && query == '')) { - vimGlobalState.searchHistoryController.pushInput(query); - vimGlobalState.searchHistoryController.reset(); - updateSearchQuery(cm, originalQuery); - clearSearchHighlight(cm); - cm.scrollTo(originalScrollPos.left, originalScrollPos.top); - CodeMirror.e_stop(e); - clearInputState(cm); - close(); - cm.focus(); - } else if (keyName == 'Up' || keyName == 'Down') { - CodeMirror.e_stop(e); - } else if (keyName == 'Ctrl-U') { - // Ctrl-U clears input. - CodeMirror.e_stop(e); - close(''); - } - } - switch (command.searchArgs.querySrc) { - case 'prompt': - var macroModeState = vimGlobalState.macroModeState; - if (macroModeState.isPlaying) { - var query = macroModeState.replaySearchQueries.shift(); - handleQuery(query, true /** ignoreCase */, false /** smartCase */); - } else { - showPrompt(cm, { - onClose: onPromptClose, - prefix: promptPrefix, - desc: searchPromptDesc, - onKeyUp: onPromptKeyUp, - onKeyDown: onPromptKeyDown - }); - } - break; - case 'wordUnderCursor': - var word = expandWordUnderCursor(cm, false /** inclusive */, - true /** forward */, false /** bigWord */, - true /** noSymbol */); - var isKeyword = true; - if (!word) { - word = expandWordUnderCursor(cm, false /** inclusive */, - true /** forward */, false /** bigWord */, - false /** noSymbol */); - isKeyword = false; - } - if (!word) { - return; - } - var query = cm.getLine(word.start.line).substring(word.start.ch, - word.end.ch); - if (isKeyword && wholeWordOnly) { - query = '\\b' + query + '\\b'; - } else { - query = escapeRegex(query); - } - - // cachedCursor is used to save the old position of the cursor - // when * or # causes vim to seek for the nearest word and shift - // the cursor before entering the motion. - vimGlobalState.jumpList.cachedCursor = cm.getCursor(); - cm.setCursor(word.start); - - handleQuery(query, true /** ignoreCase */, false /** smartCase */); - break; - } - }, - processEx: function(cm, vim, command) { - function onPromptClose(input) { - // Give the prompt some time to close so that if processCommand shows - // an error, the elements don't overlap. - vimGlobalState.exCommandHistoryController.pushInput(input); - vimGlobalState.exCommandHistoryController.reset(); - exCommandDispatcher.processCommand(cm, input); - } - function onPromptKeyDown(e, input, close) { - var keyName = CodeMirror.keyName(e), up, offset; - if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' || - (keyName == 'Backspace' && input == '')) { - vimGlobalState.exCommandHistoryController.pushInput(input); - vimGlobalState.exCommandHistoryController.reset(); - CodeMirror.e_stop(e); - clearInputState(cm); - close(); - cm.focus(); - } - if (keyName == 'Up' || keyName == 'Down') { - CodeMirror.e_stop(e); - up = keyName == 'Up' ? true : false; - offset = e.target ? e.target.selectionEnd : 0; - input = vimGlobalState.exCommandHistoryController.nextMatch(input, up) || ''; - close(input); - if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length); - } else if (keyName == 'Ctrl-U') { - // Ctrl-U clears input. - CodeMirror.e_stop(e); - close(''); - } else { - if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift') - vimGlobalState.exCommandHistoryController.reset(); - } - } - if (command.type == 'keyToEx') { - // Handle user defined Ex to Ex mappings - exCommandDispatcher.processCommand(cm, command.exArgs.input); - } else { - if (vim.visualMode) { - showPrompt(cm, { onClose: onPromptClose, prefix: ':', value: '\'<,\'>', - onKeyDown: onPromptKeyDown, selectValueOnOpen: false}); - } else { - showPrompt(cm, { onClose: onPromptClose, prefix: ':', - onKeyDown: onPromptKeyDown}); - } - } - }, - evalInput: function(cm, vim) { - // If the motion command is set, execute both the operator and motion. - // Otherwise return. - var inputState = vim.inputState; - var motion = inputState.motion; - var motionArgs = inputState.motionArgs || {}; - var operator = inputState.operator; - var operatorArgs = inputState.operatorArgs || {}; - var registerName = inputState.registerName; - var sel = vim.sel; - // TODO: Make sure cm and vim selections are identical outside visual mode. - var origHead = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.head): cm.getCursor('head')); - var origAnchor = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.anchor) : cm.getCursor('anchor')); - var oldHead = copyCursor(origHead); - var oldAnchor = copyCursor(origAnchor); - var newHead, newAnchor; - var repeat; - if (operator) { - this.recordLastEdit(vim, inputState); - } - if (inputState.repeatOverride !== undefined) { - // If repeatOverride is specified, that takes precedence over the - // input state's repeat. Used by Ex mode and can be user defined. - repeat = inputState.repeatOverride; - } else { - repeat = inputState.getRepeat(); - } - if (repeat > 0 && motionArgs.explicitRepeat) { - motionArgs.repeatIsExplicit = true; - } else if (motionArgs.noRepeat || - (!motionArgs.explicitRepeat && repeat === 0)) { - repeat = 1; - motionArgs.repeatIsExplicit = false; - } - if (inputState.selectedCharacter) { - // If there is a character input, stick it in all of the arg arrays. - motionArgs.selectedCharacter = operatorArgs.selectedCharacter = - inputState.selectedCharacter; - } - motionArgs.repeat = repeat; - clearInputState(cm); - if (motion) { - var motionResult = motions[motion](cm, origHead, motionArgs, vim); - vim.lastMotion = motions[motion]; - if (!motionResult) { - return; - } - if (motionArgs.toJumplist) { - if (!operator && cm.ace.curOp != null) - cm.ace.curOp.command.scrollIntoView = "center-animate"; // ace_patch - var jumpList = vimGlobalState.jumpList; - // if the current motion is # or *, use cachedCursor - var cachedCursor = jumpList.cachedCursor; - if (cachedCursor) { - recordJumpPosition(cm, cachedCursor, motionResult); - delete jumpList.cachedCursor; - } else { - recordJumpPosition(cm, origHead, motionResult); - } - } - if (motionResult instanceof Array) { - newAnchor = motionResult[0]; - newHead = motionResult[1]; - } else { - newHead = motionResult; - } - // TODO: Handle null returns from motion commands better. - if (!newHead) { - newHead = copyCursor(origHead); - } - if (vim.visualMode) { - if (!(vim.visualBlock && newHead.ch === Infinity)) { - newHead = clipCursorToContent(cm, newHead, vim.visualBlock); - } - if (newAnchor) { - newAnchor = clipCursorToContent(cm, newAnchor, true); - } - newAnchor = newAnchor || oldAnchor; - sel.anchor = newAnchor; - sel.head = newHead; - updateCmSelection(cm); - updateMark(cm, vim, '<', - cursorIsBefore(newAnchor, newHead) ? newAnchor - : newHead); - updateMark(cm, vim, '>', - cursorIsBefore(newAnchor, newHead) ? newHead - : newAnchor); - } else if (!operator) { - newHead = clipCursorToContent(cm, newHead); - cm.setCursor(newHead.line, newHead.ch); - } - } - if (operator) { - if (operatorArgs.lastSel) { - // Replaying a visual mode operation - newAnchor = oldAnchor; - var lastSel = operatorArgs.lastSel; - var lineOffset = Math.abs(lastSel.head.line - lastSel.anchor.line); - var chOffset = Math.abs(lastSel.head.ch - lastSel.anchor.ch); - if (lastSel.visualLine) { - // Linewise Visual mode: The same number of lines. - newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch); - } else if (lastSel.visualBlock) { - // Blockwise Visual mode: The same number of lines and columns. - newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset); - } else if (lastSel.head.line == lastSel.anchor.line) { - // Normal Visual mode within one line: The same number of characters. - newHead = Pos(oldAnchor.line, oldAnchor.ch + chOffset); - } else { - // Normal Visual mode with several lines: The same number of lines, in the - // last line the same number of characters as in the last line the last time. - newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch); - } - vim.visualMode = true; - vim.visualLine = lastSel.visualLine; - vim.visualBlock = lastSel.visualBlock; - sel = vim.sel = { - anchor: newAnchor, - head: newHead - }; - updateCmSelection(cm); - } else if (vim.visualMode) { - operatorArgs.lastSel = { - anchor: copyCursor(sel.anchor), - head: copyCursor(sel.head), - visualBlock: vim.visualBlock, - visualLine: vim.visualLine - }; - } - var curStart, curEnd, linewise, mode; - var cmSel; - if (vim.visualMode) { - // Init visual op - curStart = cursorMin(sel.head, sel.anchor); - curEnd = cursorMax(sel.head, sel.anchor); - linewise = vim.visualLine || operatorArgs.linewise; - mode = vim.visualBlock ? 'block' : - linewise ? 'line' : - 'char'; - cmSel = makeCmSelection(cm, { - anchor: curStart, - head: curEnd - }, mode); - if (linewise) { - var ranges = cmSel.ranges; - if (mode == 'block') { - // Linewise operators in visual block mode extend to end of line - for (var i = 0; i < ranges.length; i++) { - ranges[i].head.ch = lineLength(cm, ranges[i].head.line); - } - } else if (mode == 'line') { - ranges[0].head = Pos(ranges[0].head.line + 1, 0); - } - } - } else { - // Init motion op - curStart = copyCursor(newAnchor || oldAnchor); - curEnd = copyCursor(newHead || oldHead); - if (cursorIsBefore(curEnd, curStart)) { - var tmp = curStart; - curStart = curEnd; - curEnd = tmp; - } - linewise = motionArgs.linewise || operatorArgs.linewise; - if (linewise) { - // Expand selection to entire line. - expandSelectionToLine(cm, curStart, curEnd); - } else if (motionArgs.forward) { - // Clip to trailing newlines only if the motion goes forward. - clipToLine(cm, curStart, curEnd); - } - mode = 'char'; - var exclusive = !motionArgs.inclusive || linewise; - cmSel = makeCmSelection(cm, { - anchor: curStart, - head: curEnd - }, mode, exclusive); - } - cm.setSelections(cmSel.ranges, cmSel.primary); - vim.lastMotion = null; - operatorArgs.repeat = repeat; // For indent in visual mode. - operatorArgs.registerName = registerName; - // Keep track of linewise as it affects how paste and change behave. - operatorArgs.linewise = linewise; - var operatorMoveTo = operators[operator]( - cm, operatorArgs, cmSel.ranges, oldAnchor, newHead); - if (vim.visualMode) { - exitVisualMode(cm, operatorMoveTo != null); - } - if (operatorMoveTo) { - cm.setCursor(operatorMoveTo); - } - } - }, - recordLastEdit: function(vim, inputState, actionCommand) { - var macroModeState = vimGlobalState.macroModeState; - if (macroModeState.isPlaying) { return; } - vim.lastEditInputState = inputState; - vim.lastEditActionCommand = actionCommand; - macroModeState.lastInsertModeChanges.changes = []; - macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false; - } - }; - - /** - * typedef {Object{line:number,ch:number}} Cursor An object containing the - * position of the cursor. - */ - // All of the functions below return Cursor objects. - var motions = { - moveToTopLine: function(cm, _head, motionArgs) { - var line = getUserVisibleLines(cm).top + motionArgs.repeat -1; - return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); - }, - moveToMiddleLine: function(cm) { - var range = getUserVisibleLines(cm); - var line = Math.floor((range.top + range.bottom) * 0.5); - return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); - }, - moveToBottomLine: function(cm, _head, motionArgs) { - var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1; - return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); - }, - expandToLine: function(_cm, head, motionArgs) { - // Expands forward to end of line, and then to next line if repeat is - // >1. Does not handle backward motion! - var cur = head; - return Pos(cur.line + motionArgs.repeat - 1, Infinity); - }, - findNext: function(cm, _head, motionArgs) { - var state = getSearchState(cm); - var query = state.getQuery(); - if (!query) { - return; - } - var prev = !motionArgs.forward; - // If search is initiated with ? instead of /, negate direction. - prev = (state.isReversed()) ? !prev : prev; - highlightSearchMatches(cm, query); - return findNext(cm, prev/** prev */, query, motionArgs.repeat); - }, - goToMark: function(cm, _head, motionArgs, vim) { - var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter); - if (pos) { - return motionArgs.linewise ? { line: pos.line, ch: findFirstNonWhiteSpaceCharacter(cm.getLine(pos.line)) } : pos; - } - return null; - }, - moveToOtherHighlightedEnd: function(cm, _head, motionArgs, vim) { - if (vim.visualBlock && motionArgs.sameLine) { - var sel = vim.sel; - return [ - clipCursorToContent(cm, Pos(sel.anchor.line, sel.head.ch)), - clipCursorToContent(cm, Pos(sel.head.line, sel.anchor.ch)) - ]; - } else { - return ([vim.sel.head, vim.sel.anchor]); - } - }, - jumpToMark: function(cm, head, motionArgs, vim) { - var best = head; - for (var i = 0; i < motionArgs.repeat; i++) { - var cursor = best; - for (var key in vim.marks) { - if (!isLowerCase(key)) { - continue; - } - var mark = vim.marks[key].find(); - var isWrongDirection = (motionArgs.forward) ? - cursorIsBefore(mark, cursor) : cursorIsBefore(cursor, mark); - - if (isWrongDirection) { - continue; - } - if (motionArgs.linewise && (mark.line == cursor.line)) { - continue; - } - - var equal = cursorEqual(cursor, best); - var between = (motionArgs.forward) ? - cursorIsBetween(cursor, mark, best) : - cursorIsBetween(best, mark, cursor); - - if (equal || between) { - best = mark; - } - } - } - - if (motionArgs.linewise) { - // Vim places the cursor on the first non-whitespace character of - // the line if there is one, else it places the cursor at the end - // of the line, regardless of whether a mark was found. - best = Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line))); - } - return best; - }, - moveByCharacters: function(_cm, head, motionArgs) { - var cur = head; - var repeat = motionArgs.repeat; - var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat; - return Pos(cur.line, ch); - }, - moveByLines: function(cm, head, motionArgs, vim) { - var cur = head; - var endCh = cur.ch; - // Depending what our last motion was, we may want to do different - // things. If our last motion was moving vertically, we want to - // preserve the HPos from our last horizontal move. If our last motion - // was going to the end of a line, moving vertically we should go to - // the end of the line, etc. - switch (vim.lastMotion) { - case this.moveByLines: - case this.moveByDisplayLines: - case this.moveByScroll: - case this.moveToColumn: - case this.moveToEol: - endCh = vim.lastHPos; - break; - default: - vim.lastHPos = endCh; - } - var repeat = motionArgs.repeat+(motionArgs.repeatOffset||0); - var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat; - var first = cm.firstLine(); - var last = cm.lastLine(); - // Vim go to line begin or line end when cursor at first/last line and - // move to previous/next line is triggered. - if (line < first && cur.line == first){ - return this.moveToStartOfLine(cm, head, motionArgs, vim); - }else if (line > last && cur.line == last){ - return this.moveToEol(cm, head, motionArgs, vim); - } - // ace_patch{ - var fold = cm.ace.session.getFoldLine(line); - if (fold) { - if (motionArgs.forward) { - if (line > fold.start.row) - line = fold.end.row + 1; - } else { - line = fold.start.row; - } - } - // ace_patch} - if (motionArgs.toFirstChar){ - endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line)); - vim.lastHPos = endCh; - } - vim.lastHSPos = cm.charCoords(Pos(line, endCh),'div').left; - return Pos(line, endCh); - }, - moveByDisplayLines: function(cm, head, motionArgs, vim) { - var cur = head; - switch (vim.lastMotion) { - case this.moveByDisplayLines: - case this.moveByScroll: - case this.moveByLines: - case this.moveToColumn: - case this.moveToEol: - break; - default: - vim.lastHSPos = cm.charCoords(cur,'div').left; - } - var repeat = motionArgs.repeat; - var res=cm.findPosV(cur,(motionArgs.forward ? repeat : -repeat),'line',vim.lastHSPos); - if (res.hitSide) { - if (motionArgs.forward) { - var lastCharCoords = cm.charCoords(res, 'div'); - var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos }; - var res = cm.coordsChar(goalCoords, 'div'); - } else { - var resCoords = cm.charCoords(Pos(cm.firstLine(), 0), 'div'); - resCoords.left = vim.lastHSPos; - res = cm.coordsChar(resCoords, 'div'); - } - } - vim.lastHPos = res.ch; - return res; - }, - moveByPage: function(cm, head, motionArgs) { - // CodeMirror only exposes functions that move the cursor page down, so - // doing this bad hack to move the cursor and move it back. evalInput - // will move the cursor to where it should be in the end. - var curStart = head; - var repeat = motionArgs.repeat; - return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page'); - }, - moveByParagraph: function(cm, head, motionArgs) { - var dir = motionArgs.forward ? 1 : -1; - return findParagraph(cm, head, motionArgs.repeat, dir); - }, - moveByScroll: function(cm, head, motionArgs, vim) { - var scrollbox = cm.getScrollInfo(); - var curEnd = null; - var repeat = motionArgs.repeat; - if (!repeat) { - repeat = scrollbox.clientHeight / (2 * cm.defaultTextHeight()); - } - var orig = cm.charCoords(head, 'local'); - motionArgs.repeat = repeat; - var curEnd = motions.moveByDisplayLines(cm, head, motionArgs, vim); - if (!curEnd) { - return null; - } - var dest = cm.charCoords(curEnd, 'local'); - cm.scrollTo(null, scrollbox.top + dest.top - orig.top); - return curEnd; - }, - moveByWords: function(cm, head, motionArgs) { - return moveToWord(cm, head, motionArgs.repeat, !!motionArgs.forward, - !!motionArgs.wordEnd, !!motionArgs.bigWord); - }, - moveTillCharacter: function(cm, _head, motionArgs) { - var repeat = motionArgs.repeat; - var curEnd = moveToCharacter(cm, repeat, motionArgs.forward, - motionArgs.selectedCharacter); - var increment = motionArgs.forward ? -1 : 1; - recordLastCharacterSearch(increment, motionArgs); - if (!curEnd) return null; - curEnd.ch += increment; - return curEnd; - }, - moveToCharacter: function(cm, head, motionArgs) { - var repeat = motionArgs.repeat; - recordLastCharacterSearch(0, motionArgs); - return moveToCharacter(cm, repeat, motionArgs.forward, - motionArgs.selectedCharacter) || head; - }, - moveToSymbol: function(cm, head, motionArgs) { - var repeat = motionArgs.repeat; - return findSymbol(cm, repeat, motionArgs.forward, - motionArgs.selectedCharacter) || head; - }, - moveToColumn: function(cm, head, motionArgs, vim) { - var repeat = motionArgs.repeat; - // repeat is equivalent to which column we want to move to! - vim.lastHPos = repeat - 1; - vim.lastHSPos = cm.charCoords(head,'div').left; - return moveToColumn(cm, repeat); - }, - moveToEol: function(cm, head, motionArgs, vim) { - var cur = head; - vim.lastHPos = Infinity; - var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity); - var end=cm.clipPos(retval); - end.ch--; - vim.lastHSPos = cm.charCoords(end,'div').left; - return retval; - }, - moveToFirstNonWhiteSpaceCharacter: function(cm, head) { - // Go to the start of the line where the text begins, or the end for - // whitespace-only lines - var cursor = head; - return Pos(cursor.line, - findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line))); - }, - moveToMatchedSymbol: function(cm, head) { - var cursor = head; - var line = cursor.line; - var ch = cursor.ch; - var lineText = cm.getLine(line); - var symbol; - do { - symbol = lineText.charAt(ch++); - if (symbol && isMatchableSymbol(symbol)) { - var style = cm.getTokenTypeAt(Pos(line, ch)); - if (style !== "string" && style !== "comment") { - break; - } - } - } while (symbol); - if (symbol) { - var matched = cm.findMatchingBracket(Pos(line, ch)); - return matched.to; - } else { - return cursor; - } - }, - moveToStartOfLine: function(_cm, head) { - return Pos(head.line, 0); - }, - moveToLineOrEdgeOfDocument: function(cm, _head, motionArgs) { - var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine(); - if (motionArgs.repeatIsExplicit) { - lineNum = motionArgs.repeat - cm.getOption('firstLineNumber'); - } - return Pos(lineNum, - findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum))); - }, - textObjectManipulation: function(cm, head, motionArgs, vim) { - // TODO: lots of possible exceptions that can be thrown here. Try da( - // outside of a () block. - - // TODO: adding <> >< to this map doesn't work, presumably because - // they're operators - var mirroredPairs = {'(': ')', ')': '(', - '{': '}', '}': '{', - '[': ']', ']': '['}; - var selfPaired = {'\'': true, '"': true}; - - var character = motionArgs.selectedCharacter; - // 'b' refers to '()' block. - // 'B' refers to '{}' block. - if (character == 'b') { - character = '('; - } else if (character == 'B') { - character = '{'; - } - - // Inclusive is the difference between a and i - // TODO: Instead of using the additional text object map to perform text - // object operations, merge the map into the defaultKeyMap and use - // motionArgs to define behavior. Define separate entries for 'aw', - // 'iw', 'a[', 'i[', etc. - var inclusive = !motionArgs.textObjectInner; - - var tmp; - if (mirroredPairs[character]) { - tmp = selectCompanionObject(cm, head, character, inclusive); - } else if (selfPaired[character]) { - tmp = findBeginningAndEnd(cm, head, character, inclusive); - } else if (character === 'W') { - tmp = expandWordUnderCursor(cm, inclusive, true /** forward */, - true /** bigWord */); - } else if (character === 'w') { - tmp = expandWordUnderCursor(cm, inclusive, true /** forward */, - false /** bigWord */); - } else if (character === 'p') { - tmp = findParagraph(cm, head, motionArgs.repeat, 0, inclusive); - motionArgs.linewise = true; - if (vim.visualMode) { - if (!vim.visualLine) { vim.visualLine = true; } - } else { - var operatorArgs = vim.inputState.operatorArgs; - if (operatorArgs) { operatorArgs.linewise = true; } - tmp.end.line--; - } - } else { - // No text object defined for this, don't move. - return null; - } - - if (!cm.state.vim.visualMode) { - return [tmp.start, tmp.end]; - } else { - return expandSelection(cm, tmp.start, tmp.end); - } - }, - - repeatLastCharacterSearch: function(cm, head, motionArgs) { - var lastSearch = vimGlobalState.lastCharacterSearch; - var repeat = motionArgs.repeat; - var forward = motionArgs.forward === lastSearch.forward; - var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1); - cm.moveH(-increment, 'char'); - motionArgs.inclusive = forward ? true : false; - var curEnd = moveToCharacter(cm, repeat, forward, lastSearch.selectedCharacter); - if (!curEnd) { - cm.moveH(increment, 'char'); - return head; - } - curEnd.ch += increment; - return curEnd; - } - }; - - function defineMotion(name, fn) { - motions[name] = fn; - } - - function fillArray(val, times) { - var arr = []; - for (var i = 0; i < times; i++) { - arr.push(val); - } - return arr; - } - /** - * An operator acts on a text selection. It receives the list of selections - * as input. The corresponding CodeMirror selection is guaranteed to - * match the input selection. - */ - var operators = { - change: function(cm, args, ranges) { - var finalHead, text; - var vim = cm.state.vim; - vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock = vim.visualBlock; - if (!vim.visualMode) { - var anchor = ranges[0].anchor, - head = ranges[0].head; - text = cm.getRange(anchor, head); - var lastState = vim.lastEditInputState || {}; - if (lastState.motion == "moveByWords" && !isWhiteSpaceString(text)) { - // Exclude trailing whitespace if the range is not all whitespace. - var match = (/\s+$/).exec(text); - if (match && lastState.motionArgs && lastState.motionArgs.forward) { - head = offsetCursor(head, 0, - match[0].length); - text = text.slice(0, - match[0].length); - } - } - var prevLineEnd = new Pos(anchor.line - 1, Number.MAX_VALUE); - var wasLastLine = cm.firstLine() == cm.lastLine(); - if (head.line > cm.lastLine() && args.linewise && !wasLastLine) { - cm.replaceRange('', prevLineEnd, head); - } else { - cm.replaceRange('', anchor, head); - } - if (args.linewise) { - // Push the next line back down, if there is a next line. - if (!wasLastLine) { - cm.setCursor(prevLineEnd); - CodeMirror.commands.newlineAndIndent(cm); - } - // make sure cursor ends up at the end of the line. - anchor.ch = Number.MAX_VALUE; - } - finalHead = anchor; - } else { - text = cm.getSelection(); - var replacement = fillArray('', ranges.length); - cm.replaceSelections(replacement); - finalHead = cursorMin(ranges[0].head, ranges[0].anchor); - } - vimGlobalState.registerController.pushText( - args.registerName, 'change', text, - args.linewise, ranges.length > 1); - actions.enterInsertMode(cm, {head: finalHead}, cm.state.vim); - }, - // delete is a javascript keyword. - 'delete': function(cm, args, ranges) { - var finalHead, text; - var vim = cm.state.vim; - if (!vim.visualBlock) { - var anchor = ranges[0].anchor, - head = ranges[0].head; - if (args.linewise && - head.line != cm.firstLine() && - anchor.line == cm.lastLine() && - anchor.line == head.line - 1) { - // Special case for dd on last line (and first line). - if (anchor.line == cm.firstLine()) { - anchor.ch = 0; - } else { - anchor = Pos(anchor.line - 1, lineLength(cm, anchor.line - 1)); - } - } - text = cm.getRange(anchor, head); - cm.replaceRange('', anchor, head); - finalHead = anchor; - if (args.linewise) { - finalHead = motions.moveToFirstNonWhiteSpaceCharacter(cm, anchor); - } - } else { - text = cm.getSelection(); - var replacement = fillArray('', ranges.length); - cm.replaceSelections(replacement); - finalHead = ranges[0].anchor; - } - vimGlobalState.registerController.pushText( - args.registerName, 'delete', text, - args.linewise, vim.visualBlock); - var includeLineBreak = vim.insertMode - return clipCursorToContent(cm, finalHead, includeLineBreak); - }, - indent: function(cm, args, ranges) { - var vim = cm.state.vim; - var startLine = ranges[0].anchor.line; - var endLine = vim.visualBlock ? - ranges[ranges.length - 1].anchor.line : - ranges[0].head.line; - // In visual mode, n> shifts the selection right n times, instead of - // shifting n lines right once. - var repeat = (vim.visualMode) ? args.repeat : 1; - if (args.linewise) { - // The only way to delete a newline is to delete until the start of - // the next line, so in linewise mode evalInput will include the next - // line. We don't want this in indent, so we go back a line. - endLine--; - } - for (var i = startLine; i <= endLine; i++) { - for (var j = 0; j < repeat; j++) { - cm.indentLine(i, args.indentRight); - } - } - return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor); - }, - changeCase: function(cm, args, ranges, oldAnchor, newHead) { - var selections = cm.getSelections(); - var swapped = []; - var toLower = args.toLower; - for (var j = 0; j < selections.length; j++) { - var toSwap = selections[j]; - var text = ''; - if (toLower === true) { - text = toSwap.toLowerCase(); - } else if (toLower === false) { - text = toSwap.toUpperCase(); - } else { - for (var i = 0; i < toSwap.length; i++) { - var character = toSwap.charAt(i); - text += isUpperCase(character) ? character.toLowerCase() : - character.toUpperCase(); - } - } - swapped.push(text); - } - cm.replaceSelections(swapped); - if (args.shouldMoveCursor){ - return newHead; - } else if (!cm.state.vim.visualMode && args.linewise && ranges[0].anchor.line + 1 == ranges[0].head.line) { - return motions.moveToFirstNonWhiteSpaceCharacter(cm, oldAnchor); - } else if (args.linewise){ - return oldAnchor; - } else { - return cursorMin(ranges[0].anchor, ranges[0].head); - } - }, - yank: function(cm, args, ranges, oldAnchor) { - var vim = cm.state.vim; - var text = cm.getSelection(); - var endPos = vim.visualMode - ? cursorMin(vim.sel.anchor, vim.sel.head, ranges[0].head, ranges[0].anchor) - : oldAnchor; - vimGlobalState.registerController.pushText( - args.registerName, 'yank', - text, args.linewise, vim.visualBlock); - return endPos; - } - }; - - function defineOperator(name, fn) { - operators[name] = fn; - } - - var actions = { - jumpListWalk: function(cm, actionArgs, vim) { - if (vim.visualMode) { - return; - } - var repeat = actionArgs.repeat; - var forward = actionArgs.forward; - var jumpList = vimGlobalState.jumpList; - - var mark = jumpList.move(cm, forward ? repeat : -repeat); - var markPos = mark ? mark.find() : undefined; - markPos = markPos ? markPos : cm.getCursor(); - cm.setCursor(markPos); - cm.ace.curOp.command.scrollIntoView = "center-animate"; // ace_patch - }, - scroll: function(cm, actionArgs, vim) { - if (vim.visualMode) { - return; - } - var repeat = actionArgs.repeat || 1; - var lineHeight = cm.defaultTextHeight(); - var top = cm.getScrollInfo().top; - var delta = lineHeight * repeat; - var newPos = actionArgs.forward ? top + delta : top - delta; - var cursor = copyCursor(cm.getCursor()); - var cursorCoords = cm.charCoords(cursor, 'local'); - if (actionArgs.forward) { - if (newPos > cursorCoords.top) { - cursor.line += (newPos - cursorCoords.top) / lineHeight; - cursor.line = Math.ceil(cursor.line); - cm.setCursor(cursor); - cursorCoords = cm.charCoords(cursor, 'local'); - cm.scrollTo(null, cursorCoords.top); - } else { - // Cursor stays within bounds. Just reposition the scroll window. - cm.scrollTo(null, newPos); - } - } else { - var newBottom = newPos + cm.getScrollInfo().clientHeight; - if (newBottom < cursorCoords.bottom) { - cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight; - cursor.line = Math.floor(cursor.line); - cm.setCursor(cursor); - cursorCoords = cm.charCoords(cursor, 'local'); - cm.scrollTo( - null, cursorCoords.bottom - cm.getScrollInfo().clientHeight); - } else { - // Cursor stays within bounds. Just reposition the scroll window. - cm.scrollTo(null, newPos); - } - } - }, - scrollToCursor: function(cm, actionArgs) { - var lineNum = cm.getCursor().line; - var charCoords = cm.charCoords(Pos(lineNum, 0), 'local'); - var height = cm.getScrollInfo().clientHeight; - var y = charCoords.top; - var lineHeight = charCoords.bottom - y; - switch (actionArgs.position) { - case 'center': y = y - (height / 2) + lineHeight; - break; - case 'bottom': y = y - height + lineHeight*1.4; - break; - case 'top': y = y + lineHeight*0.4; - break; - } - cm.scrollTo(null, y); - }, - replayMacro: function(cm, actionArgs, vim) { - var registerName = actionArgs.selectedCharacter; - var repeat = actionArgs.repeat; - var macroModeState = vimGlobalState.macroModeState; - if (registerName == '@') { - registerName = macroModeState.latestRegister; - } - while(repeat--){ - executeMacroRegister(cm, vim, macroModeState, registerName); - } - }, - enterMacroRecordMode: function(cm, actionArgs) { - var macroModeState = vimGlobalState.macroModeState; - var registerName = actionArgs.selectedCharacter; - if (vimGlobalState.registerController.isValidRegister(registerName)) { - macroModeState.enterMacroRecordMode(cm, registerName); - } - }, - toggleOverwrite: function(cm) { - if (!cm.state.overwrite) { - cm.toggleOverwrite(true); - cm.setOption('keyMap', 'vim-replace'); - CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"}); - } else { - cm.toggleOverwrite(false); - cm.setOption('keyMap', 'vim-insert'); - CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"}); - } - }, - enterInsertMode: function(cm, actionArgs, vim) { - if (cm.getOption('readOnly')) { return; } - vim.insertMode = true; - vim.insertModeRepeat = actionArgs && actionArgs.repeat || 1; - var insertAt = (actionArgs) ? actionArgs.insertAt : null; - var sel = vim.sel; - var head = actionArgs.head || cm.getCursor('head'); - var height = cm.listSelections().length; - if (insertAt == 'eol') { - head = Pos(head.line, lineLength(cm, head.line)); - } else if (insertAt == 'charAfter') { - head = offsetCursor(head, 0, 1); - } else if (insertAt == 'firstNonBlank') { - head = motions.moveToFirstNonWhiteSpaceCharacter(cm, head); - } else if (insertAt == 'startOfSelectedArea') { - if (!vim.visualBlock) { - if (sel.head.line < sel.anchor.line) { - head = sel.head; - } else { - head = Pos(sel.anchor.line, 0); - } - } else { - head = Pos( - Math.min(sel.head.line, sel.anchor.line), - Math.min(sel.head.ch, sel.anchor.ch)); - height = Math.abs(sel.head.line - sel.anchor.line) + 1; - } - } else if (insertAt == 'endOfSelectedArea') { - if (!vim.visualBlock) { - if (sel.head.line >= sel.anchor.line) { - head = offsetCursor(sel.head, 0, 1); - } else { - head = Pos(sel.anchor.line, 0); - } - } else { - head = Pos( - Math.min(sel.head.line, sel.anchor.line), - Math.max(sel.head.ch + 1, sel.anchor.ch)); - height = Math.abs(sel.head.line - sel.anchor.line) + 1; - } - } else if (insertAt == 'inplace') { - if (vim.visualMode){ - return; - } - } - cm.setOption('disableInput', false); - if (actionArgs && actionArgs.replace) { - // Handle Replace-mode as a special case of insert mode. - cm.toggleOverwrite(true); - cm.setOption('keyMap', 'vim-replace'); - CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"}); - } else { - cm.toggleOverwrite(false); - cm.setOption('keyMap', 'vim-insert'); - CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"}); - } - if (!vimGlobalState.macroModeState.isPlaying) { - // Only record if not replaying. - cm.on('change', onChange); - CodeMirror.on(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown); - } - if (vim.visualMode) { - exitVisualMode(cm); - } - selectForInsert(cm, head, height); - }, - toggleVisualMode: function(cm, actionArgs, vim) { - var repeat = actionArgs.repeat; - var anchor = cm.getCursor(); - var head; - // TODO: The repeat should actually select number of characters/lines - // equal to the repeat times the size of the previous visual - // operation. - if (!vim.visualMode) { - // Entering visual mode - vim.visualMode = true; - vim.visualLine = !!actionArgs.linewise; - vim.visualBlock = !!actionArgs.blockwise; - head = clipCursorToContent( - cm, Pos(anchor.line, anchor.ch + repeat - 1), - true /** includeLineBreak */); - vim.sel = { - anchor: anchor, - head: head - }; - CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : vim.visualBlock ? "blockwise" : ""}); - updateCmSelection(cm); - updateMark(cm, vim, '<', cursorMin(anchor, head)); - updateMark(cm, vim, '>', cursorMax(anchor, head)); - } else if (vim.visualLine ^ actionArgs.linewise || - vim.visualBlock ^ actionArgs.blockwise) { - // Toggling between modes - vim.visualLine = !!actionArgs.linewise; - vim.visualBlock = !!actionArgs.blockwise; - CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : vim.visualBlock ? "blockwise" : ""}); - updateCmSelection(cm); - } else { - exitVisualMode(cm); - } - }, - reselectLastSelection: function(cm, _actionArgs, vim) { - var lastSelection = vim.lastSelection; - if (vim.visualMode) { - updateLastSelection(cm, vim); - } - if (lastSelection) { - var anchor = lastSelection.anchorMark.find(); - var head = lastSelection.headMark.find(); - if (!anchor || !head) { - // If the marks have been destroyed due to edits, do nothing. - return; - } - vim.sel = { - anchor: anchor, - head: head - }; - vim.visualMode = true; - vim.visualLine = lastSelection.visualLine; - vim.visualBlock = lastSelection.visualBlock; - updateCmSelection(cm); - updateMark(cm, vim, '<', cursorMin(anchor, head)); - updateMark(cm, vim, '>', cursorMax(anchor, head)); - CodeMirror.signal(cm, 'vim-mode-change', { - mode: 'visual', - subMode: vim.visualLine ? 'linewise' : - vim.visualBlock ? 'blockwise' : ''}); - } - }, - joinLines: function(cm, actionArgs, vim) { - var curStart, curEnd; - if (vim.visualMode) { - curStart = cm.getCursor('anchor'); - curEnd = cm.getCursor('head'); - if (cursorIsBefore(curEnd, curStart)) { - var tmp = curEnd; - curEnd = curStart; - curStart = tmp; - } - curEnd.ch = lineLength(cm, curEnd.line) - 1; - } else { - // Repeat is the number of lines to join. Minimum 2 lines. - var repeat = Math.max(actionArgs.repeat, 2); - curStart = cm.getCursor(); - curEnd = clipCursorToContent(cm, Pos(curStart.line + repeat - 1, - Infinity)); - } - var finalCh = 0; - for (var i = curStart.line; i < curEnd.line; i++) { - finalCh = lineLength(cm, curStart.line); - var tmp = Pos(curStart.line + 1, - lineLength(cm, curStart.line + 1)); - var text = cm.getRange(curStart, tmp); - text = text.replace(/\n\s*/g, ' '); - cm.replaceRange(text, curStart, tmp); - } - var curFinalPos = Pos(curStart.line, finalCh); - if (vim.visualMode) { - exitVisualMode(cm, false); - } - cm.setCursor(curFinalPos); - }, - newLineAndEnterInsertMode: function(cm, actionArgs, vim) { - vim.insertMode = true; - var insertAt = copyCursor(cm.getCursor()); - if (insertAt.line === cm.firstLine() && !actionArgs.after) { - // Special case for inserting newline before start of document. - cm.replaceRange('\n', Pos(cm.firstLine(), 0)); - cm.setCursor(cm.firstLine(), 0); - } else { - insertAt.line = (actionArgs.after) ? insertAt.line : - insertAt.line - 1; - insertAt.ch = lineLength(cm, insertAt.line); - cm.setCursor(insertAt); - var newlineFn = CodeMirror.commands.newlineAndIndentContinueComment || - CodeMirror.commands.newlineAndIndent; - newlineFn(cm); - } - this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim); - }, - paste: function(cm, actionArgs, vim) { - var cur = copyCursor(cm.getCursor()); - var register = vimGlobalState.registerController.getRegister( - actionArgs.registerName); - var text = register.toString(); - if (!text) { - return; - } - if (actionArgs.matchIndent) { - var tabSize = cm.getOption("tabSize"); - // length that considers tabs and tabSize - var whitespaceLength = function(str) { - var tabs = (str.split("\t").length - 1); - var spaces = (str.split(" ").length - 1); - return tabs * tabSize + spaces * 1; - }; - var currentLine = cm.getLine(cm.getCursor().line); - var indent = whitespaceLength(currentLine.match(/^\s*/)[0]); - // chomp last newline b/c don't want it to match /^\s*/gm - var chompedText = text.replace(/\n$/, ''); - var wasChomped = text !== chompedText; - var firstIndent = whitespaceLength(text.match(/^\s*/)[0]); - var text = chompedText.replace(/^\s*/gm, function(wspace) { - var newIndent = indent + (whitespaceLength(wspace) - firstIndent); - if (newIndent < 0) { - return ""; - } - else if (cm.getOption("indentWithTabs")) { - var quotient = Math.floor(newIndent / tabSize); - return Array(quotient + 1).join('\t'); - } - else { - return Array(newIndent + 1).join(' '); - } - }); - text += wasChomped ? "\n" : ""; - } - if (actionArgs.repeat > 1) { - var text = Array(actionArgs.repeat + 1).join(text); - } - var linewise = register.linewise; - var blockwise = register.blockwise; - if (linewise && !blockwise) { - if(vim.visualMode) { - text = vim.visualLine ? text.slice(0, -1) : '\n' + text.slice(0, text.length - 1) + '\n'; - } else if (actionArgs.after) { - // Move the newline at the end to the start instead, and paste just - // before the newline character of the line we are on right now. - text = '\n' + text.slice(0, text.length - 1); - cur.ch = lineLength(cm, cur.line); - } else { - cur.ch = 0; - } - } else { - if (blockwise) { - text = text.split('\n'); - for (var i = 0; i < text.length; i++) { - text[i] = (text[i] == '') ? ' ' : text[i]; - } - } - cur.ch += actionArgs.after ? 1 : 0; - } - var curPosFinal; - var idx; - if (vim.visualMode) { - // save the pasted text for reselection if the need arises - vim.lastPastedText = text; - var lastSelectionCurEnd; - var selectedArea = getSelectedAreaRange(cm, vim); - var selectionStart = selectedArea[0]; - var selectionEnd = selectedArea[1]; - var selectedText = cm.getSelection(); - var selections = cm.listSelections(); - var emptyStrings = new Array(selections.length).join('1').split('1'); - // save the curEnd marker before it get cleared due to cm.replaceRange. - if (vim.lastSelection) { - lastSelectionCurEnd = vim.lastSelection.headMark.find(); - } - // push the previously selected text to unnamed register - vimGlobalState.registerController.unnamedRegister.setText(selectedText); - if (blockwise) { - // first delete the selected text - cm.replaceSelections(emptyStrings); - // Set new selections as per the block length of the yanked text - selectionEnd = Pos(selectionStart.line + text.length-1, selectionStart.ch); - cm.setCursor(selectionStart); - selectBlock(cm, selectionEnd); - cm.replaceSelections(text); - curPosFinal = selectionStart; - } else if (vim.visualBlock) { - cm.replaceSelections(emptyStrings); - cm.setCursor(selectionStart); - cm.replaceRange(text, selectionStart, selectionStart); - curPosFinal = selectionStart; - } else { - cm.replaceRange(text, selectionStart, selectionEnd); - curPosFinal = cm.posFromIndex(cm.indexFromPos(selectionStart) + text.length - 1); - } - // restore the the curEnd marker - if(lastSelectionCurEnd) { - vim.lastSelection.headMark = cm.setBookmark(lastSelectionCurEnd); - } - if (linewise) { - curPosFinal.ch=0; - } - } else { - if (blockwise) { - cm.setCursor(cur); - for (var i = 0; i < text.length; i++) { - var line = cur.line+i; - if (line > cm.lastLine()) { - cm.replaceRange('\n', Pos(line, 0)); - } - var lastCh = lineLength(cm, line); - if (lastCh < cur.ch) { - extendLineToColumn(cm, line, cur.ch); - } - } - cm.setCursor(cur); - selectBlock(cm, Pos(cur.line + text.length-1, cur.ch)); - cm.replaceSelections(text); - curPosFinal = cur; - } else { - cm.replaceRange(text, cur); - // Now fine tune the cursor to where we want it. - if (linewise && actionArgs.after) { - curPosFinal = Pos( - cur.line + 1, - findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1))); - } else if (linewise && !actionArgs.after) { - curPosFinal = Pos( - cur.line, - findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line))); - } else if (!linewise && actionArgs.after) { - idx = cm.indexFromPos(cur); - curPosFinal = cm.posFromIndex(idx + text.length - 1); - } else { - idx = cm.indexFromPos(cur); - curPosFinal = cm.posFromIndex(idx + text.length); - } - } - } - if (vim.visualMode) { - exitVisualMode(cm, false); - } - cm.setCursor(curPosFinal); - }, - undo: function(cm, actionArgs) { - cm.operation(function() { - repeatFn(cm, CodeMirror.commands.undo, actionArgs.repeat)(); - cm.setCursor(cm.getCursor('anchor')); - }); - }, - redo: function(cm, actionArgs) { - repeatFn(cm, CodeMirror.commands.redo, actionArgs.repeat)(); - }, - setRegister: function(_cm, actionArgs, vim) { - vim.inputState.registerName = actionArgs.selectedCharacter; - }, - setMark: function(cm, actionArgs, vim) { - var markName = actionArgs.selectedCharacter; - updateMark(cm, vim, markName, cm.getCursor()); - }, - replace: function(cm, actionArgs, vim) { - var replaceWith = actionArgs.selectedCharacter; - var curStart = cm.getCursor(); - var replaceTo; - var curEnd; - var selections = cm.listSelections(); - if (vim.visualMode) { - curStart = cm.getCursor('start'); - curEnd = cm.getCursor('end'); - } else { - var line = cm.getLine(curStart.line); - replaceTo = curStart.ch + actionArgs.repeat; - if (replaceTo > line.length) { - replaceTo=line.length; - } - curEnd = Pos(curStart.line, replaceTo); - } - if (replaceWith=='\n') { - if (!vim.visualMode) cm.replaceRange('', curStart, curEnd); - // special case, where vim help says to replace by just one line-break - (CodeMirror.commands.newlineAndIndentContinueComment || CodeMirror.commands.newlineAndIndent)(cm); - } else { - var replaceWithStr = cm.getRange(curStart, curEnd); - //replace all characters in range by selected, but keep linebreaks - replaceWithStr = replaceWithStr.replace(/[^\n]/g, replaceWith); - if (vim.visualBlock) { - // Tabs are split in visua block before replacing - var spaces = new Array(cm.getOption("tabSize")+1).join(' '); - replaceWithStr = cm.getSelection(); - replaceWithStr = replaceWithStr.replace(/\t/g, spaces).replace(/[^\n]/g, replaceWith).split('\n'); - cm.replaceSelections(replaceWithStr); - } else { - cm.replaceRange(replaceWithStr, curStart, curEnd); - } - if (vim.visualMode) { - curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ? - selections[0].anchor : selections[0].head; - cm.setCursor(curStart); - exitVisualMode(cm, false); - } else { - cm.setCursor(offsetCursor(curEnd, 0, -1)); - } - } - }, - incrementNumberToken: function(cm, actionArgs) { - var cur = cm.getCursor(); - var lineStr = cm.getLine(cur.line); - var re = /(-?)(?:(0x)([\da-f]+)|(0b|0|)(\d+))/gi; - var match; - var start; - var end; - var numberStr; - while ((match = re.exec(lineStr)) !== null) { - start = match.index; - end = start + match[0].length; - if (cur.ch < end)break; - } - if (!actionArgs.backtrack && (end <= cur.ch))return; - if (match) { - var baseStr = match[2] || match[4] - var digits = match[3] || match[5] - var increment = actionArgs.increase ? 1 : -1; - var base = {'0b': 2, '0': 8, '': 10, '0x': 16}[baseStr.toLowerCase()]; - var number = parseInt(match[1] + digits, base) + (increment * actionArgs.repeat); - numberStr = number.toString(base); - var zeroPadding = baseStr ? new Array(digits.length - numberStr.length + 1 + match[1].length).join('0') : '' - if (numberStr.charAt(0) === '-') { - numberStr = '-' + baseStr + zeroPadding + numberStr.substr(1); - } else { - numberStr = baseStr + zeroPadding + numberStr; - } - var from = Pos(cur.line, start); - var to = Pos(cur.line, end); - cm.replaceRange(numberStr, from, to); - } else { - return; - } - cm.setCursor(Pos(cur.line, start + numberStr.length - 1)); - }, - repeatLastEdit: function(cm, actionArgs, vim) { - var lastEditInputState = vim.lastEditInputState; - if (!lastEditInputState) { return; } - var repeat = actionArgs.repeat; - if (repeat && actionArgs.repeatIsExplicit) { - vim.lastEditInputState.repeatOverride = repeat; - } else { - repeat = vim.lastEditInputState.repeatOverride || repeat; - } - repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */); - }, - indent: function(cm, actionArgs) { - cm.indentLine(cm.getCursor().line, actionArgs.indentRight); - }, - exitInsertMode: exitInsertMode - }; - - function defineAction(name, fn) { - actions[name] = fn; - } - - /* - * Below are miscellaneous utility functions used by vim.js - */ - - /** - * Clips cursor to ensure that line is within the buffer's range - * If includeLineBreak is true, then allow cur.ch == lineLength. - */ - function clipCursorToContent(cm, cur, includeLineBreak) { - var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() ); - var maxCh = lineLength(cm, line) - 1; - maxCh = (includeLineBreak) ? maxCh + 1 : maxCh; - var ch = Math.min(Math.max(0, cur.ch), maxCh); - return Pos(line, ch); - } - function copyArgs(args) { - var ret = {}; - for (var prop in args) { - if (args.hasOwnProperty(prop)) { - ret[prop] = args[prop]; - } - } - return ret; - } - function offsetCursor(cur, offsetLine, offsetCh) { - if (typeof offsetLine === 'object') { - offsetCh = offsetLine.ch; - offsetLine = offsetLine.line; - } - return Pos(cur.line + offsetLine, cur.ch + offsetCh); - } - function getOffset(anchor, head) { - return { - line: head.line - anchor.line, - ch: head.line - anchor.line - }; - } - function commandMatches(keys, keyMap, context, inputState) { - // Partial matches are not applied. They inform the key handler - // that the current key sequence is a subsequence of a valid key - // sequence, so that the key buffer is not cleared. - var match, partial = [], full = []; - for (var i = 0; i < keyMap.length; i++) { - var command = keyMap[i]; - if (context == 'insert' && command.context != 'insert' || - command.context && command.context != context || - inputState.operator && command.type == 'action' || - !(match = commandMatch(keys, command.keys))) { continue; } - if (match == 'partial') { partial.push(command); } - if (match == 'full') { full.push(command); } - } - return { - partial: partial.length && partial, - full: full.length && full - }; - } - function commandMatch(pressed, mapped) { - if (mapped.slice(-11) == '') { - // Last character matches anything. - var prefixLen = mapped.length - 11; - var pressedPrefix = pressed.slice(0, prefixLen); - var mappedPrefix = mapped.slice(0, prefixLen); - return pressedPrefix == mappedPrefix && pressed.length > prefixLen ? 'full' : - mappedPrefix.indexOf(pressedPrefix) == 0 ? 'partial' : false; - } else { - return pressed == mapped ? 'full' : - mapped.indexOf(pressed) == 0 ? 'partial' : false; - } - } - function lastChar(keys) { - var match = /^.*(<[^>]+>)$/.exec(keys); - var selectedCharacter = match ? match[1] : keys.slice(-1); - if (selectedCharacter.length > 1){ - switch(selectedCharacter){ - case '': - selectedCharacter='\n'; - break; - case '': - selectedCharacter=' '; - break; - default: - selectedCharacter=''; - break; - } - } - return selectedCharacter; - } - function repeatFn(cm, fn, repeat) { - return function() { - for (var i = 0; i < repeat; i++) { - fn(cm); - } - }; - } - function copyCursor(cur) { - return Pos(cur.line, cur.ch); - } - function cursorEqual(cur1, cur2) { - return cur1.ch == cur2.ch && cur1.line == cur2.line; - } - function cursorIsBefore(cur1, cur2) { - if (cur1.line < cur2.line) { - return true; - } - if (cur1.line == cur2.line && cur1.ch < cur2.ch) { - return true; - } - return false; - } - function cursorMin(cur1, cur2) { - if (arguments.length > 2) { - cur2 = cursorMin.apply(undefined, Array.prototype.slice.call(arguments, 1)); - } - return cursorIsBefore(cur1, cur2) ? cur1 : cur2; - } - function cursorMax(cur1, cur2) { - if (arguments.length > 2) { - cur2 = cursorMax.apply(undefined, Array.prototype.slice.call(arguments, 1)); - } - return cursorIsBefore(cur1, cur2) ? cur2 : cur1; - } - function cursorIsBetween(cur1, cur2, cur3) { - // returns true if cur2 is between cur1 and cur3. - var cur1before2 = cursorIsBefore(cur1, cur2); - var cur2before3 = cursorIsBefore(cur2, cur3); - return cur1before2 && cur2before3; - } - function lineLength(cm, lineNum) { - return cm.getLine(lineNum).length; - } - function trim(s) { - if (s.trim) { - return s.trim(); - } - return s.replace(/^\s+|\s+$/g, ''); - } - function escapeRegex(s) { - return s.replace(/([.?*+$\[\]\/\\(){}|\-])/g, '\\$1'); - } - function extendLineToColumn(cm, lineNum, column) { - var endCh = lineLength(cm, lineNum); - var spaces = new Array(column-endCh+1).join(' '); - cm.setCursor(Pos(lineNum, endCh)); - cm.replaceRange(spaces, cm.getCursor()); - } - // This functions selects a rectangular block - // of text with selectionEnd as any of its corner - // Height of block: - // Difference in selectionEnd.line and first/last selection.line - // Width of the block: - // Distance between selectionEnd.ch and any(first considered here) selection.ch - function selectBlock(cm, selectionEnd) { - var selections = [], ranges = cm.listSelections(); - var head = copyCursor(cm.clipPos(selectionEnd)); - var isClipped = !cursorEqual(selectionEnd, head); - var curHead = cm.getCursor('head'); - var primIndex = getIndex(ranges, curHead); - var wasClipped = cursorEqual(ranges[primIndex].head, ranges[primIndex].anchor); - var max = ranges.length - 1; - var index = max - primIndex > primIndex ? max : 0; - var base = ranges[index].anchor; - - var firstLine = Math.min(base.line, head.line); - var lastLine = Math.max(base.line, head.line); - var baseCh = base.ch, headCh = head.ch; - - var dir = ranges[index].head.ch - baseCh; - var newDir = headCh - baseCh; - if (dir > 0 && newDir <= 0) { - baseCh++; - if (!isClipped) { headCh--; } - } else if (dir < 0 && newDir >= 0) { - baseCh--; - if (!wasClipped) { headCh++; } - } else if (dir < 0 && newDir == -1) { - baseCh--; - headCh++; - } - for (var line = firstLine; line <= lastLine; line++) { - var range = {anchor: new Pos(line, baseCh), head: new Pos(line, headCh)}; - selections.push(range); - } - cm.setSelections(selections); - selectionEnd.ch = headCh; - base.ch = baseCh; - return base; - } - function selectForInsert(cm, head, height) { - var sel = []; - for (var i = 0; i < height; i++) { - var lineHead = offsetCursor(head, i, 0); - sel.push({anchor: lineHead, head: lineHead}); - } - cm.setSelections(sel, 0); - } - // getIndex returns the index of the cursor in the selections. - function getIndex(ranges, cursor, end) { - for (var i = 0; i < ranges.length; i++) { - var atAnchor = end != 'head' && cursorEqual(ranges[i].anchor, cursor); - var atHead = end != 'anchor' && cursorEqual(ranges[i].head, cursor); - if (atAnchor || atHead) { - return i; - } - } - return -1; - } - function getSelectedAreaRange(cm, vim) { - var lastSelection = vim.lastSelection; - var getCurrentSelectedAreaRange = function() { - var selections = cm.listSelections(); - var start = selections[0]; - var end = selections[selections.length-1]; - var selectionStart = cursorIsBefore(start.anchor, start.head) ? start.anchor : start.head; - var selectionEnd = cursorIsBefore(end.anchor, end.head) ? end.head : end.anchor; - return [selectionStart, selectionEnd]; - }; - var getLastSelectedAreaRange = function() { - var selectionStart = cm.getCursor(); - var selectionEnd = cm.getCursor(); - var block = lastSelection.visualBlock; - if (block) { - var width = block.width; - var height = block.height; - selectionEnd = Pos(selectionStart.line + height, selectionStart.ch + width); - var selections = []; - // selectBlock creates a 'proper' rectangular block. - // We do not want that in all cases, so we manually set selections. - for (var i = selectionStart.line; i < selectionEnd.line; i++) { - var anchor = Pos(i, selectionStart.ch); - var head = Pos(i, selectionEnd.ch); - var range = {anchor: anchor, head: head}; - selections.push(range); - } - cm.setSelections(selections); - } else { - var start = lastSelection.anchorMark.find(); - var end = lastSelection.headMark.find(); - var line = end.line - start.line; - var ch = end.ch - start.ch; - selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch}; - if (lastSelection.visualLine) { - selectionStart = Pos(selectionStart.line, 0); - selectionEnd = Pos(selectionEnd.line, lineLength(cm, selectionEnd.line)); - } - cm.setSelection(selectionStart, selectionEnd); - } - return [selectionStart, selectionEnd]; - }; - if (!vim.visualMode) { - // In case of replaying the action. - return getLastSelectedAreaRange(); - } else { - return getCurrentSelectedAreaRange(); - } - } - // Updates the previous selection with the current selection's values. This - // should only be called in visual mode. - function updateLastSelection(cm, vim) { - var anchor = vim.sel.anchor; - var head = vim.sel.head; - // To accommodate the effect of lastPastedText in the last selection - if (vim.lastPastedText) { - head = cm.posFromIndex(cm.indexFromPos(anchor) + vim.lastPastedText.length); - vim.lastPastedText = null; - } - vim.lastSelection = {'anchorMark': cm.setBookmark(anchor), - 'headMark': cm.setBookmark(head), - 'anchor': copyCursor(anchor), - 'head': copyCursor(head), - 'visualMode': vim.visualMode, - 'visualLine': vim.visualLine, - 'visualBlock': vim.visualBlock}; - } - function expandSelection(cm, start, end) { - var sel = cm.state.vim.sel; - var head = sel.head; - var anchor = sel.anchor; - var tmp; - if (cursorIsBefore(end, start)) { - tmp = end; - end = start; - start = tmp; - } - if (cursorIsBefore(head, anchor)) { - head = cursorMin(start, head); - anchor = cursorMax(anchor, end); - } else { - anchor = cursorMin(start, anchor); - head = cursorMax(head, end); - head = offsetCursor(head, 0, -1); - if (head.ch == -1 && head.line != cm.firstLine()) { - head = Pos(head.line - 1, lineLength(cm, head.line - 1)); - } - } - return [anchor, head]; - } - /** - * Updates the CodeMirror selection to match the provided vim selection. - * If no arguments are given, it uses the current vim selection state. - */ - function updateCmSelection(cm, sel, mode) { - var vim = cm.state.vim; - sel = sel || vim.sel; - var mode = mode || - vim.visualLine ? 'line' : vim.visualBlock ? 'block' : 'char'; - var cmSel = makeCmSelection(cm, sel, mode); - cm.setSelections(cmSel.ranges, cmSel.primary); - updateFakeCursor(cm); - } - function makeCmSelection(cm, sel, mode, exclusive) { - var head = copyCursor(sel.head); - var anchor = copyCursor(sel.anchor); - if (mode == 'char') { - var headOffset = !exclusive && !cursorIsBefore(sel.head, sel.anchor) ? 1 : 0; - var anchorOffset = cursorIsBefore(sel.head, sel.anchor) ? 1 : 0; - head = offsetCursor(sel.head, 0, headOffset); - anchor = offsetCursor(sel.anchor, 0, anchorOffset); - return { - ranges: [{anchor: anchor, head: head}], - primary: 0 - }; - } else if (mode == 'line') { - if (!cursorIsBefore(sel.head, sel.anchor)) { - anchor.ch = 0; - - var lastLine = cm.lastLine(); - if (head.line > lastLine) { - head.line = lastLine; - } - head.ch = lineLength(cm, head.line); - } else { - head.ch = 0; - anchor.ch = lineLength(cm, anchor.line); - } - return { - ranges: [{anchor: anchor, head: head}], - primary: 0 - }; - } else if (mode == 'block') { - var top = Math.min(anchor.line, head.line), - left = Math.min(anchor.ch, head.ch), - bottom = Math.max(anchor.line, head.line), - right = Math.max(anchor.ch, head.ch) + 1; - var height = bottom - top + 1; - var primary = head.line == top ? 0 : height - 1; - var ranges = []; - for (var i = 0; i < height; i++) { - ranges.push({ - anchor: Pos(top + i, left), - head: Pos(top + i, right) - }); - } - return { - ranges: ranges, - primary: primary - }; - } - } - function getHead(cm) { - var cur = cm.getCursor('head'); - if (cm.getSelection().length == 1) { - // Small corner case when only 1 character is selected. The "real" - // head is the left of head and anchor. - cur = cursorMin(cur, cm.getCursor('anchor')); - } - return cur; - } - - /** - * If moveHead is set to false, the CodeMirror selection will not be - * touched. The caller assumes the responsibility of putting the cursor - * in the right place. - */ - function exitVisualMode(cm, moveHead) { - var vim = cm.state.vim; - if (moveHead !== false) { - cm.setCursor(clipCursorToContent(cm, vim.sel.head)); - } - updateLastSelection(cm, vim); - vim.visualMode = false; - vim.visualLine = false; - vim.visualBlock = false; - CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); - if (vim.fakeCursor) { - vim.fakeCursor.clear(); - } - } - - // Remove any trailing newlines from the selection. For - // example, with the caret at the start of the last word on the line, - // 'dw' should word, but not the newline, while 'w' should advance the - // caret to the first character of the next line. - function clipToLine(cm, curStart, curEnd) { - var selection = cm.getRange(curStart, curEnd); - // Only clip if the selection ends with trailing newline + whitespace - if (/\n\s*$/.test(selection)) { - var lines = selection.split('\n'); - // We know this is all whitespace. - lines.pop(); - - // Cases: - // 1. Last word is an empty line - do not clip the trailing '\n' - // 2. Last word is not an empty line - clip the trailing '\n' - var line; - // Find the line containing the last word, and clip all whitespace up - // to it. - for (var line = lines.pop(); lines.length > 0 && line && isWhiteSpaceString(line); line = lines.pop()) { - curEnd.line--; - curEnd.ch = 0; - } - // If the last word is not an empty line, clip an additional newline - if (line) { - curEnd.line--; - curEnd.ch = lineLength(cm, curEnd.line); - } else { - curEnd.ch = 0; - } - } - } - - // Expand the selection to line ends. - function expandSelectionToLine(_cm, curStart, curEnd) { - curStart.ch = 0; - curEnd.ch = 0; - curEnd.line++; - } - - function findFirstNonWhiteSpaceCharacter(text) { - if (!text) { - return 0; - } - var firstNonWS = text.search(/\S/); - return firstNonWS == -1 ? text.length : firstNonWS; - } - - function expandWordUnderCursor(cm, inclusive, _forward, bigWord, noSymbol) { - var cur = getHead(cm); - var line = cm.getLine(cur.line); - var idx = cur.ch; - - // Seek to first word or non-whitespace character, depending on if - // noSymbol is true. - var test = noSymbol ? wordCharTest[0] : bigWordCharTest [0]; - while (!test(line.charAt(idx))) { - idx++; - if (idx >= line.length) { return null; } - } - - if (bigWord) { - test = bigWordCharTest[0]; - } else { - test = wordCharTest[0]; - if (!test(line.charAt(idx))) { - test = wordCharTest[1]; - } - } - - var end = idx, start = idx; - while (test(line.charAt(end)) && end < line.length) { end++; } - while (test(line.charAt(start)) && start >= 0) { start--; } - start++; - - if (inclusive) { - // If present, include all whitespace after word. - // Otherwise, include all whitespace before word, except indentation. - var wordEnd = end; - while (/\s/.test(line.charAt(end)) && end < line.length) { end++; } - if (wordEnd == end) { - var wordStart = start; - while (/\s/.test(line.charAt(start - 1)) && start > 0) { start--; } - if (!start) { start = wordStart; } - } - } - return { start: Pos(cur.line, start), end: Pos(cur.line, end) }; - } - - function recordJumpPosition(cm, oldCur, newCur) { - if (!cursorEqual(oldCur, newCur)) { - vimGlobalState.jumpList.add(cm, oldCur, newCur); - } - } - - function recordLastCharacterSearch(increment, args) { - vimGlobalState.lastCharacterSearch.increment = increment; - vimGlobalState.lastCharacterSearch.forward = args.forward; - vimGlobalState.lastCharacterSearch.selectedCharacter = args.selectedCharacter; - } - - var symbolToMode = { - '(': 'bracket', ')': 'bracket', '{': 'bracket', '}': 'bracket', - '[': 'section', ']': 'section', - '*': 'comment', '/': 'comment', - 'm': 'method', 'M': 'method', - '#': 'preprocess' - }; - var findSymbolModes = { - bracket: { - isComplete: function(state) { - if (state.nextCh === state.symb) { - state.depth++; - if (state.depth >= 1)return true; - } else if (state.nextCh === state.reverseSymb) { - state.depth--; - } - return false; - } - }, - section: { - init: function(state) { - state.curMoveThrough = true; - state.symb = (state.forward ? ']' : '[') === state.symb ? '{' : '}'; - }, - isComplete: function(state) { - return state.index === 0 && state.nextCh === state.symb; - } - }, - comment: { - isComplete: function(state) { - var found = state.lastCh === '*' && state.nextCh === '/'; - state.lastCh = state.nextCh; - return found; - } - }, - // TODO: The original Vim implementation only operates on level 1 and 2. - // The current implementation doesn't check for code block level and - // therefore it operates on any levels. - method: { - init: function(state) { - state.symb = (state.symb === 'm' ? '{' : '}'); - state.reverseSymb = state.symb === '{' ? '}' : '{'; - }, - isComplete: function(state) { - if (state.nextCh === state.symb)return true; - return false; - } - }, - preprocess: { - init: function(state) { - state.index = 0; - }, - isComplete: function(state) { - if (state.nextCh === '#') { - var token = state.lineText.match(/#(\w+)/)[1]; - if (token === 'endif') { - if (state.forward && state.depth === 0) { - return true; - } - state.depth++; - } else if (token === 'if') { - if (!state.forward && state.depth === 0) { - return true; - } - state.depth--; - } - if (token === 'else' && state.depth === 0)return true; - } - return false; - } - } - }; - function findSymbol(cm, repeat, forward, symb) { - var cur = copyCursor(cm.getCursor()); - var increment = forward ? 1 : -1; - var endLine = forward ? cm.lineCount() : -1; - var curCh = cur.ch; - var line = cur.line; - var lineText = cm.getLine(line); - var state = { - lineText: lineText, - nextCh: lineText.charAt(curCh), - lastCh: null, - index: curCh, - symb: symb, - reverseSymb: (forward ? { ')': '(', '}': '{' } : { '(': ')', '{': '}' })[symb], - forward: forward, - depth: 0, - curMoveThrough: false - }; - var mode = symbolToMode[symb]; - if (!mode)return cur; - var init = findSymbolModes[mode].init; - var isComplete = findSymbolModes[mode].isComplete; - if (init) { init(state); } - while (line !== endLine && repeat) { - state.index += increment; - state.nextCh = state.lineText.charAt(state.index); - if (!state.nextCh) { - line += increment; - state.lineText = cm.getLine(line) || ''; - if (increment > 0) { - state.index = 0; - } else { - var lineLen = state.lineText.length; - state.index = (lineLen > 0) ? (lineLen-1) : 0; - } - state.nextCh = state.lineText.charAt(state.index); - } - if (isComplete(state)) { - cur.line = line; - cur.ch = state.index; - repeat--; - } - } - if (state.nextCh || state.curMoveThrough) { - return Pos(line, state.index); - } - return cur; - } - - /* - * Returns the boundaries of the next word. If the cursor in the middle of - * the word, then returns the boundaries of the current word, starting at - * the cursor. If the cursor is at the start/end of a word, and we are going - * forward/backward, respectively, find the boundaries of the next word. - * - * @param {CodeMirror} cm CodeMirror object. - * @param {Cursor} cur The cursor position. - * @param {boolean} forward True to search forward. False to search - * backward. - * @param {boolean} bigWord True if punctuation count as part of the word. - * False if only [a-zA-Z0-9] characters count as part of the word. - * @param {boolean} emptyLineIsWord True if empty lines should be treated - * as words. - * @return {Object{from:number, to:number, line: number}} The boundaries of - * the word, or null if there are no more words. - */ - function findWord(cm, cur, forward, bigWord, emptyLineIsWord) { - var lineNum = cur.line; - var pos = cur.ch; - var line = cm.getLine(lineNum); - var dir = forward ? 1 : -1; - var charTests = bigWord ? bigWordCharTest: wordCharTest; - - if (emptyLineIsWord && line == '') { - lineNum += dir; - line = cm.getLine(lineNum); - if (!isLine(cm, lineNum)) { - return null; - } - pos = (forward) ? 0 : line.length; - } - - while (true) { - if (emptyLineIsWord && line == '') { - return { from: 0, to: 0, line: lineNum }; - } - var stop = (dir > 0) ? line.length : -1; - var wordStart = stop, wordEnd = stop; - // Find bounds of next word. - while (pos != stop) { - var foundWord = false; - for (var i = 0; i < charTests.length && !foundWord; ++i) { - if (charTests[i](line.charAt(pos))) { - wordStart = pos; - // Advance to end of word. - while (pos != stop && charTests[i](line.charAt(pos))) { - pos += dir; - } - wordEnd = pos; - foundWord = wordStart != wordEnd; - if (wordStart == cur.ch && lineNum == cur.line && - wordEnd == wordStart + dir) { - // We started at the end of a word. Find the next one. - continue; - } else { - return { - from: Math.min(wordStart, wordEnd + 1), - to: Math.max(wordStart, wordEnd), - line: lineNum }; - } - } - } - if (!foundWord) { - pos += dir; - } - } - // Advance to next/prev line. - lineNum += dir; - if (!isLine(cm, lineNum)) { - return null; - } - line = cm.getLine(lineNum); - pos = (dir > 0) ? 0 : line.length; - } - } - - /** - * @param {CodeMirror} cm CodeMirror object. - * @param {Pos} cur The position to start from. - * @param {int} repeat Number of words to move past. - * @param {boolean} forward True to search forward. False to search - * backward. - * @param {boolean} wordEnd True to move to end of word. False to move to - * beginning of word. - * @param {boolean} bigWord True if punctuation count as part of the word. - * False if only alphabet characters count as part of the word. - * @return {Cursor} The position the cursor should move to. - */ - function moveToWord(cm, cur, repeat, forward, wordEnd, bigWord) { - var curStart = copyCursor(cur); - var words = []; - if (forward && !wordEnd || !forward && wordEnd) { - repeat++; - } - // For 'e', empty lines are not considered words, go figure. - var emptyLineIsWord = !(forward && wordEnd); - for (var i = 0; i < repeat; i++) { - var word = findWord(cm, cur, forward, bigWord, emptyLineIsWord); - if (!word) { - var eodCh = lineLength(cm, cm.lastLine()); - words.push(forward - ? {line: cm.lastLine(), from: eodCh, to: eodCh} - : {line: 0, from: 0, to: 0}); - break; - } - words.push(word); - cur = Pos(word.line, forward ? (word.to - 1) : word.from); - } - var shortCircuit = words.length != repeat; - var firstWord = words[0]; - var lastWord = words.pop(); - if (forward && !wordEnd) { - // w - if (!shortCircuit && (firstWord.from != curStart.ch || firstWord.line != curStart.line)) { - // We did not start in the middle of a word. Discard the extra word at the end. - lastWord = words.pop(); - } - return Pos(lastWord.line, lastWord.from); - } else if (forward && wordEnd) { - return Pos(lastWord.line, lastWord.to - 1); - } else if (!forward && wordEnd) { - // ge - if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) { - // We did not start in the middle of a word. Discard the extra word at the end. - lastWord = words.pop(); - } - return Pos(lastWord.line, lastWord.to); - } else { - // b - return Pos(lastWord.line, lastWord.from); - } - } - - function moveToCharacter(cm, repeat, forward, character) { - var cur = cm.getCursor(); - var start = cur.ch; - var idx; - for (var i = 0; i < repeat; i ++) { - var line = cm.getLine(cur.line); - idx = charIdxInLine(start, line, character, forward, true); - if (idx == -1) { - return null; - } - start = idx; - } - return Pos(cm.getCursor().line, idx); - } - - function moveToColumn(cm, repeat) { - // repeat is always >= 1, so repeat - 1 always corresponds - // to the column we want to go to. - var line = cm.getCursor().line; - return clipCursorToContent(cm, Pos(line, repeat - 1)); - } - - function updateMark(cm, vim, markName, pos) { - if (!inArray(markName, validMarks)) { - return; - } - if (vim.marks[markName]) { - vim.marks[markName].clear(); - } - vim.marks[markName] = cm.setBookmark(pos); - } - - function charIdxInLine(start, line, character, forward, includeChar) { - // Search for char in line. - // motion_options: {forward, includeChar} - // If includeChar = true, include it too. - // If forward = true, search forward, else search backwards. - // If char is not found on this line, do nothing - var idx; - if (forward) { - idx = line.indexOf(character, start + 1); - if (idx != -1 && !includeChar) { - idx -= 1; - } - } else { - idx = line.lastIndexOf(character, start - 1); - if (idx != -1 && !includeChar) { - idx += 1; - } - } - return idx; - } - - function findParagraph(cm, head, repeat, dir, inclusive) { - var line = head.line; - var min = cm.firstLine(); - var max = cm.lastLine(); - var start, end, i = line; - function isEmpty(i) { return !/\S/.test(cm.getLine(i)); } // ace_patch - function isBoundary(i, dir, any) { - if (any) { return isEmpty(i) != isEmpty(i + dir); } - return !isEmpty(i) && isEmpty(i + dir); - } - function skipFold(i) { - dir = dir > 0 ? 1 : -1; - var foldLine = cm.ace.session.getFoldLine(i); - if (foldLine) { - if (i + dir > foldLine.start.row && i + dir < foldLine.end.row) - dir = (dir > 0 ? foldLine.end.row : foldLine.start.row) - i; - } - } - if (dir) { - while (min <= i && i <= max && repeat > 0) { - skipFold(i); - if (isBoundary(i, dir)) { repeat--; } - i += dir; - } - return new Pos(i, 0); - } - - var vim = cm.state.vim; - if (vim.visualLine && isBoundary(line, 1, true)) { - var anchor = vim.sel.anchor; - if (isBoundary(anchor.line, -1, true)) { - if (!inclusive || anchor.line != line) { - line += 1; - } - } - } - var startState = isEmpty(line); - for (i = line; i <= max && repeat; i++) { - if (isBoundary(i, 1, true)) { - if (!inclusive || isEmpty(i) != startState) { - repeat--; - } - } - } - end = new Pos(i, 0); - // select boundary before paragraph for the last one - if (i > max && !startState) { startState = true; } - else { inclusive = false; } - for (i = line; i > min; i--) { - if (!inclusive || isEmpty(i) == startState || i == line) { - if (isBoundary(i, -1, true)) { break; } - } - } - start = new Pos(i, 0); - return { start: start, end: end }; - } - - // TODO: perhaps this finagling of start and end positions belonds - // in codemirror/replaceRange? - function selectCompanionObject(cm, head, symb, inclusive) { - var cur = head, start, end; - - var bracketRegexp = ({ - '(': /[()]/, ')': /[()]/, - '[': /[[\]]/, ']': /[[\]]/, - '{': /[{}]/, '}': /[{}]/})[symb]; - var openSym = ({ - '(': '(', ')': '(', - '[': '[', ']': '[', - '{': '{', '}': '{'})[symb]; - var curChar = cm.getLine(cur.line).charAt(cur.ch); - // Due to the behavior of scanForBracket, we need to add an offset if the - // cursor is on a matching open bracket. - var offset = curChar === openSym ? 1 : 0; - - start = cm.scanForBracket(Pos(cur.line, cur.ch + offset), -1, null, {'bracketRegex': bracketRegexp}); - end = cm.scanForBracket(Pos(cur.line, cur.ch + offset), 1, null, {'bracketRegex': bracketRegexp}); - - if (!start || !end) { - return { start: cur, end: cur }; - } - - start = start.pos; - end = end.pos; - - if ((start.line == end.line && start.ch > end.ch) - || (start.line > end.line)) { - var tmp = start; - start = end; - end = tmp; - } - - if (inclusive) { - end.ch += 1; - } else { - start.ch += 1; - } - - return { start: start, end: end }; - } - - // Takes in a symbol and a cursor and tries to simulate text objects that - // have identical opening and closing symbols - // TODO support across multiple lines - function findBeginningAndEnd(cm, head, symb, inclusive) { - var cur = copyCursor(head); - var line = cm.getLine(cur.line); - var chars = line.split(''); - var start, end, i, len; - var firstIndex = chars.indexOf(symb); - - // the decision tree is to always look backwards for the beginning first, - // but if the cursor is in front of the first instance of the symb, - // then move the cursor forward - if (cur.ch < firstIndex) { - cur.ch = firstIndex; - // Why is this line even here??? - // cm.setCursor(cur.line, firstIndex+1); - } - // otherwise if the cursor is currently on the closing symbol - else if (firstIndex < cur.ch && chars[cur.ch] == symb) { - end = cur.ch; // assign end to the current cursor - --cur.ch; // make sure to look backwards - } - - // if we're currently on the symbol, we've got a start - if (chars[cur.ch] == symb && !end) { - start = cur.ch + 1; // assign start to ahead of the cursor - } else { - // go backwards to find the start - for (i = cur.ch; i > -1 && !start; i--) { - if (chars[i] == symb) { - start = i + 1; - } - } - } - - // look forwards for the end symbol - if (start && !end) { - for (i = start, len = chars.length; i < len && !end; i++) { - if (chars[i] == symb) { - end = i; - } - } - } - - // nothing found - if (!start || !end) { - return { start: cur, end: cur }; - } - - // include the symbols - if (inclusive) { - --start; ++end; - } - - return { - start: Pos(cur.line, start), - end: Pos(cur.line, end) - }; - } - - // Search functions - defineOption('pcre', true, 'boolean'); - function SearchState() {} - SearchState.prototype = { - getQuery: function() { - return vimGlobalState.query; - }, - setQuery: function(query) { - vimGlobalState.query = query; - }, - getOverlay: function() { - return this.searchOverlay; - }, - setOverlay: function(overlay) { - this.searchOverlay = overlay; - }, - isReversed: function() { - return vimGlobalState.isReversed; - }, - setReversed: function(reversed) { - vimGlobalState.isReversed = reversed; - }, - getScrollbarAnnotate: function() { - return this.annotate; - }, - setScrollbarAnnotate: function(annotate) { - this.annotate = annotate; - } - }; - function getSearchState(cm) { - var vim = cm.state.vim; - return vim.searchState_ || (vim.searchState_ = new SearchState()); - } - function dialog(cm, template, shortText, onClose, options) { - if (cm.openDialog) { - cm.openDialog(template, onClose, { bottom: true, value: options.value, - onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp, - selectValueOnOpen: false, onClose: function() { - if (cm.state.vim) { - cm.state.vim.status = ""; - cm.ace.renderer.$loop.schedule(cm.ace.renderer.CHANGE_CURSOR); - } - }}); - } - else { - onClose(prompt(shortText, '')); - } - } - - function splitBySlash(argString) { - return splitBySeparator(argString, '/'); - } - - function findUnescapedSlashes(argString) { - return findUnescapedSeparators(argString, '/'); - } - - function splitBySeparator(argString, separator) { - var slashes = findUnescapedSeparators(argString, separator) || []; - if (!slashes.length) return []; - var tokens = []; - // in case of strings like foo/bar - if (slashes[0] !== 0) return; - for (var i = 0; i < slashes.length; i++) { - if (typeof slashes[i] == 'number') - tokens.push(argString.substring(slashes[i] + 1, slashes[i+1])); - } - return tokens; - } - - function findUnescapedSeparators(str, separator) { - if (!separator) - separator = '/'; - - var escapeNextChar = false; - var slashes = []; - for (var i = 0; i < str.length; i++) { - var c = str.charAt(i); - if (!escapeNextChar && c == separator) { - slashes.push(i); - } - escapeNextChar = !escapeNextChar && (c == '\\'); - } - return slashes; - } - - // Translates a search string from ex (vim) syntax into javascript form. - function translateRegex(str) { - // When these match, add a '\' if unescaped or remove one if escaped. - var specials = '|(){'; - // Remove, but never add, a '\' for these. - var unescape = '}'; - var escapeNextChar = false; - var out = []; - for (var i = -1; i < str.length; i++) { - var c = str.charAt(i) || ''; - var n = str.charAt(i+1) || ''; - var specialComesNext = (n && specials.indexOf(n) != -1); - if (escapeNextChar) { - if (c !== '\\' || !specialComesNext) { - out.push(c); - } - escapeNextChar = false; - } else { - if (c === '\\') { - escapeNextChar = true; - // Treat the unescape list as special for removing, but not adding '\'. - if (n && unescape.indexOf(n) != -1) { - specialComesNext = true; - } - // Not passing this test means removing a '\'. - if (!specialComesNext || n === '\\') { - out.push(c); - } - } else { - out.push(c); - if (specialComesNext && n !== '\\') { - out.push('\\'); - } - } - } - } - return out.join(''); - } - - // Translates the replace part of a search and replace from ex (vim) syntax into - // javascript form. Similar to translateRegex, but additionally fixes back references - // (translates '\[0..9]' to '$[0..9]') and follows different rules for escaping '$'. - var charUnescapes = {'\\n': '\n', '\\r': '\r', '\\t': '\t'}; - function translateRegexReplace(str) { - var escapeNextChar = false; - var out = []; - for (var i = -1; i < str.length; i++) { - var c = str.charAt(i) || ''; - var n = str.charAt(i+1) || ''; - if (charUnescapes[c + n]) { - out.push(charUnescapes[c+n]); - i++; - } else if (escapeNextChar) { - // At any point in the loop, escapeNextChar is true if the previous - // character was a '\' and was not escaped. - out.push(c); - escapeNextChar = false; - } else { - if (c === '\\') { - escapeNextChar = true; - if ((isNumber(n) || n === '$')) { - out.push('$'); - } else if (n !== '/' && n !== '\\') { - out.push('\\'); - } - } else { - if (c === '$') { - out.push('$'); - } - out.push(c); - if (n === '/') { - out.push('\\'); - } - } - } - } - return out.join(''); - } - - // Unescape \ and / in the replace part, for PCRE mode. - var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'}; - function unescapeRegexReplace(str) { - var stream = new CodeMirror.StringStream(str); - var output = []; - while (!stream.eol()) { - // Search for \. - while (stream.peek() && stream.peek() != '\\') { - output.push(stream.next()); - } - var matched = false; - for (var matcher in unescapes) { - if (stream.match(matcher, true)) { - matched = true; - output.push(unescapes[matcher]); - break; - } - } - if (!matched) { - // Don't change anything - output.push(stream.next()); - } - } - return output.join(''); - } - - /** - * Extract the regular expression from the query and return a Regexp object. - * Returns null if the query is blank. - * If ignoreCase is passed in, the Regexp object will have the 'i' flag set. - * If smartCase is passed in, and the query contains upper case letters, - * then ignoreCase is overridden, and the 'i' flag will not be set. - * If the query contains the /i in the flag part of the regular expression, - * then both ignoreCase and smartCase are ignored, and 'i' will be passed - * through to the Regex object. - */ - function parseQuery(query, ignoreCase, smartCase) { - // First update the last search register - var lastSearchRegister = vimGlobalState.registerController.getRegister('/'); - lastSearchRegister.setText(query); - // Check if the query is already a regex. - if (query instanceof RegExp) { return query; } - // First try to extract regex + flags from the input. If no flags found, - // extract just the regex. IE does not accept flags directly defined in - // the regex string in the form /regex/flags - var slashes = findUnescapedSlashes(query); - var regexPart; - var forceIgnoreCase; - if (!slashes.length) { - // Query looks like 'regexp' - regexPart = query; - } else { - // Query looks like 'regexp/...' - regexPart = query.substring(0, slashes[0]); - var flagsPart = query.substring(slashes[0]); - forceIgnoreCase = (flagsPart.indexOf('i') != -1); - } - if (!regexPart) { - return null; - } - if (!getOption('pcre')) { - regexPart = translateRegex(regexPart); - } - if (smartCase) { - ignoreCase = (/^[^A-Z]*$/).test(regexPart); - } - var regexp = new RegExp(regexPart, - (ignoreCase || forceIgnoreCase) ? 'i' : undefined); - return regexp; - } - function showConfirm(cm, text) { - if (cm.openNotification) { - cm.openNotification('' + text + '', - {bottom: true, duration: 5000}); - } else { - alert(text); - } - } - function makePrompt(prefix, desc) { - var raw = '' + - (prefix || "") + ''; - if (desc) - raw += ' ' + desc + ''; - return raw; - } - var searchPromptDesc = '(Javascript regexp)'; - function showPrompt(cm, options) { - var shortText = (options.prefix || '') + ' ' + (options.desc || ''); - var prompt = makePrompt(options.prefix, options.desc); - dialog(cm, prompt, shortText, options.onClose, options); - } - function regexEqual(r1, r2) { - if (r1 instanceof RegExp && r2 instanceof RegExp) { - var props = ['global', 'multiline', 'ignoreCase', 'source']; - for (var i = 0; i < props.length; i++) { - var prop = props[i]; - if (r1[prop] !== r2[prop]) { - return false; - } - } - return true; - } - return false; - } - // Returns true if the query is valid. - function updateSearchQuery(cm, rawQuery, ignoreCase, smartCase) { - if (!rawQuery) { - return; - } - var state = getSearchState(cm); - var query = parseQuery(rawQuery, !!ignoreCase, !!smartCase); - if (!query) { - return; - } - highlightSearchMatches(cm, query); - if (regexEqual(query, state.getQuery())) { - return query; - } - state.setQuery(query); - return query; - } - function searchOverlay(query) { - if (query.source.charAt(0) == '^') { - var matchSol = true; - } - return { - token: function(stream) { - if (matchSol && !stream.sol()) { - stream.skipToEnd(); - return; - } - var match = stream.match(query, false); - if (match) { - if (match[0].length == 0) { - // Matched empty string, skip to next. - stream.next(); - return 'searching'; - } - if (!stream.sol()) { - // Backtrack 1 to match \b - stream.backUp(1); - if (!query.exec(stream.next() + match[0])) { - stream.next(); - return null; - } - } - stream.match(query); - return 'searching'; - } - while (!stream.eol()) { - stream.next(); - if (stream.match(query, false)) break; - } - }, - query: query - }; - } - function highlightSearchMatches(cm, query) { - var searchState = getSearchState(cm); - var overlay = searchState.getOverlay(); - if (!overlay || query != overlay.query) { - if (overlay) { - cm.removeOverlay(overlay); - } - overlay = searchOverlay(query); - cm.addOverlay(overlay); - if (cm.showMatchesOnScrollbar) { - if (searchState.getScrollbarAnnotate()) { - searchState.getScrollbarAnnotate().clear(); - } - searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query)); - } - searchState.setOverlay(overlay); - } - } - function findNext(cm, prev, query, repeat) { - if (repeat === undefined) { repeat = 1; } - return cm.operation(function() { - var pos = cm.getCursor(); - var cursor = cm.getSearchCursor(query, pos); - for (var i = 0; i < repeat; i++) { - var found = cursor.find(prev); - if (i == 0 && found && cursorEqual(cursor.from(), pos)) { found = cursor.find(prev); } - if (!found) { - // SearchCursor may have returned null because it hit EOF, wrap - // around and try again. - cursor = cm.getSearchCursor(query, - (prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) ); - if (!cursor.find(prev)) { - return; - } - } - } - return cursor.from(); - }); - } - function clearSearchHighlight(cm) { - var state = getSearchState(cm); - cm.removeOverlay(getSearchState(cm).getOverlay()); - state.setOverlay(null); - if (state.getScrollbarAnnotate()) { - state.getScrollbarAnnotate().clear(); - state.setScrollbarAnnotate(null); - } - } - /** - * Check if pos is in the specified range, INCLUSIVE. - * Range can be specified with 1 or 2 arguments. - * If the first range argument is an array, treat it as an array of line - * numbers. Match pos against any of the lines. - * If the first range argument is a number, - * if there is only 1 range argument, check if pos has the same line - * number - * if there are 2 range arguments, then check if pos is in between the two - * range arguments. - */ - function isInRange(pos, start, end) { - if (typeof pos != 'number') { - // Assume it is a cursor position. Get the line number. - pos = pos.line; - } - if (start instanceof Array) { - return inArray(pos, start); - } else { - if (end) { - return (pos >= start && pos <= end); - } else { - return pos == start; - } - } - } - function getUserVisibleLines(cm) { - // ace_patch{ - var renderer = cm.ace.renderer; - return { - top: renderer.getFirstFullyVisibleRow(), - bottom: renderer.getLastFullyVisibleRow() - } - // ace_patch} - } - - function getMarkPos(cm, vim, markName) { - /* TODO reenable when selection history in ace is implemented - if (markName == '\'') { - var history = cm.doc.history.done; - var event = history[history.length - 2]; - return event && event.ranges && event.ranges[0].head; - } else if (markName == '.') { - if (cm.doc.history.lastModTime == 0) { - return // If no changes, bail out; don't bother to copy or reverse history array. - } else { - var changeHistory = cm.doc.history.done.filter(function(el){ if (el.changes !== undefined) { return el } }); - changeHistory.reverse(); - var lastEditPos = changeHistory[0].changes[0].to; - } - return lastEditPos; - } - */ - - var mark = vim.marks[markName]; - return mark && mark.find(); - } - - var ExCommandDispatcher = function() { - this.buildCommandMap_(); - }; - ExCommandDispatcher.prototype = { - processCommand: function(cm, input, opt_params) { - var that = this; - cm.operation(function () { - cm.curOp.isVimOp = true; - that._processCommand(cm, input, opt_params); - }); - }, - _processCommand: function(cm, input, opt_params) { - var vim = cm.state.vim; - var commandHistoryRegister = vimGlobalState.registerController.getRegister(':'); - var previousCommand = commandHistoryRegister.toString(); - if (vim.visualMode) { - exitVisualMode(cm); - } - var inputStream = new CodeMirror.StringStream(input); - // update ": with the latest command whether valid or invalid - commandHistoryRegister.setText(input); - var params = opt_params || {}; - params.input = input; - try { - this.parseInput_(cm, inputStream, params); - } catch(e) { - showConfirm(cm, e); - throw e; - } - var command; - var commandName; - if (!params.commandName) { - // If only a line range is defined, move to the line. - if (params.line !== undefined) { - commandName = 'move'; - } - } else { - command = this.matchCommand_(params.commandName); - if (command) { - commandName = command.name; - if (command.excludeFromCommandHistory) { - commandHistoryRegister.setText(previousCommand); - } - this.parseCommandArgs_(inputStream, params, command); - if (command.type == 'exToKey') { - // Handle Ex to Key mapping. - for (var i = 0; i < command.toKeys.length; i++) { - CodeMirror.Vim.handleKey(cm, command.toKeys[i], 'mapping'); - } - return; - } else if (command.type == 'exToEx') { - // Handle Ex to Ex mapping. - this.processCommand(cm, command.toInput); - return; - } - } - } - if (!commandName) { - showConfirm(cm, 'Not an editor command ":' + input + '"'); - return; - } - try { - exCommands[commandName](cm, params); - // Possibly asynchronous commands (e.g. substitute, which might have a - // user confirmation), are responsible for calling the callback when - // done. All others have it taken care of for them here. - if ((!command || !command.possiblyAsync) && params.callback) { - params.callback(); - } - } catch(e) { - showConfirm(cm, e); - throw e; - } - }, - parseInput_: function(cm, inputStream, result) { - inputStream.eatWhile(':'); - // Parse range. - if (inputStream.eat('%')) { - result.line = cm.firstLine(); - result.lineEnd = cm.lastLine(); - } else { - result.line = this.parseLineSpec_(cm, inputStream); - if (result.line !== undefined && inputStream.eat(',')) { - result.lineEnd = this.parseLineSpec_(cm, inputStream); - } - } - - // Parse command name. - var commandMatch = inputStream.match(/^(\w+)/); - if (commandMatch) { - result.commandName = commandMatch[1]; - } else { - result.commandName = inputStream.match(/.*/)[0]; - } - - return result; - }, - parseLineSpec_: function(cm, inputStream) { - var numberMatch = inputStream.match(/^(\d+)/); - if (numberMatch) { - // Absolute line number plus offset (N+M or N-M) is probably a typo, - // not something the user actually wanted. (NB: vim does allow this.) - return parseInt(numberMatch[1], 10) - 1; - } - switch (inputStream.next()) { - case '.': - return this.parseLineSpecOffset_(inputStream, cm.getCursor().line); - case '$': - return this.parseLineSpecOffset_(inputStream, cm.lastLine()); - case '\'': - var markName = inputStream.next(); - var markPos = getMarkPos(cm, cm.state.vim, markName); - if (!markPos) throw new Error('Mark not set'); - return this.parseLineSpecOffset_(inputStream, markPos.line); - case '-': - case '+': - inputStream.backUp(1); - // Offset is relative to current line if not otherwise specified. - return this.parseLineSpecOffset_(inputStream, cm.getCursor().line); - default: - inputStream.backUp(1); - return undefined; - } - }, - parseLineSpecOffset_: function(inputStream, line) { - var offsetMatch = inputStream.match(/^([+-])?(\d+)/); - if (offsetMatch) { - var offset = parseInt(offsetMatch[2], 10); - if (offsetMatch[1] == "-") { - line -= offset; - } else { - line += offset; - } - } - return line; - }, - parseCommandArgs_: function(inputStream, params, command) { - if (inputStream.eol()) { - return; - } - params.argString = inputStream.match(/.*/)[0]; - // Parse command-line arguments - var delim = command.argDelimiter || /\s+/; - var args = trim(params.argString).split(delim); - if (args.length && args[0]) { - params.args = args; - } - }, - matchCommand_: function(commandName) { - // Return the command in the command map that matches the shortest - // prefix of the passed in command name. The match is guaranteed to be - // unambiguous if the defaultExCommandMap's shortNames are set up - // correctly. (see @code{defaultExCommandMap}). - for (var i = commandName.length; i > 0; i--) { - var prefix = commandName.substring(0, i); - if (this.commandMap_[prefix]) { - var command = this.commandMap_[prefix]; - if (command.name.indexOf(commandName) === 0) { - return command; - } - } - } - return null; - }, - buildCommandMap_: function() { - this.commandMap_ = {}; - for (var i = 0; i < defaultExCommandMap.length; i++) { - var command = defaultExCommandMap[i]; - var key = command.shortName || command.name; - this.commandMap_[key] = command; - } - }, - map: function(lhs, rhs, ctx) { - if (lhs != ':' && lhs.charAt(0) == ':') { - if (ctx) { throw Error('Mode not supported for ex mappings'); } - var commandName = lhs.substring(1); - if (rhs != ':' && rhs.charAt(0) == ':') { - // Ex to Ex mapping - this.commandMap_[commandName] = { - name: commandName, - type: 'exToEx', - toInput: rhs.substring(1), - user: true - }; - } else { - // Ex to key mapping - this.commandMap_[commandName] = { - name: commandName, - type: 'exToKey', - toKeys: rhs, - user: true - }; - } - } else { - if (rhs != ':' && rhs.charAt(0) == ':') { - // Key to Ex mapping. - var mapping = { - keys: lhs, - type: 'keyToEx', - exArgs: { input: rhs.substring(1) } - }; - if (ctx) { mapping.context = ctx; } - defaultKeymap.unshift(mapping); - } else { - // Key to key mapping - var mapping = { - keys: lhs, - type: 'keyToKey', - toKeys: rhs - }; - if (ctx) { mapping.context = ctx; } - defaultKeymap.unshift(mapping); - } - } - }, - unmap: function(lhs, ctx) { - if (lhs != ':' && lhs.charAt(0) == ':') { - // Ex to Ex or Ex to key mapping - if (ctx) { throw Error('Mode not supported for ex mappings'); } - var commandName = lhs.substring(1); - if (this.commandMap_[commandName] && this.commandMap_[commandName].user) { - delete this.commandMap_[commandName]; - return; - } - } else { - // Key to Ex or key to key mapping - var keys = lhs; - for (var i = 0; i < defaultKeymap.length; i++) { - if (keys == defaultKeymap[i].keys - && defaultKeymap[i].context === ctx) { - defaultKeymap.splice(i, 1); - return; - } - } - } - // ace_patch - } - }; - - var exCommands = { - colorscheme: function(cm, params) { - if (!params.args || params.args.length < 1) { - showConfirm(cm, cm.getOption('theme')); - return; - } - cm.setOption('theme', params.args[0]); - }, - map: function(cm, params, ctx) { - var mapArgs = params.args; - if (!mapArgs || mapArgs.length < 2) { - if (cm) { - showConfirm(cm, 'Invalid mapping: ' + params.input); - } - return; - } - exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx); - }, - imap: function(cm, params) { this.map(cm, params, 'insert'); }, - nmap: function(cm, params) { this.map(cm, params, 'normal'); }, - vmap: function(cm, params) { this.map(cm, params, 'visual'); }, - unmap: function(cm, params, ctx) { - var mapArgs = params.args; - if (!mapArgs || mapArgs.length < 1) { - if (cm) { - showConfirm(cm, 'No such mapping: ' + params.input); - } - return; - } - exCommandDispatcher.unmap(mapArgs[0], ctx); - }, - move: function(cm, params) { - commandDispatcher.processCommand(cm, cm.state.vim, { - type: 'motion', - motion: 'moveToLineOrEdgeOfDocument', - motionArgs: { forward: false, explicitRepeat: true, - linewise: true }, - repeatOverride: params.line+1}); - }, - set: function(cm, params) { - var setArgs = params.args; - // Options passed through to the setOption/getOption calls. May be passed in by the - // local/global versions of the set command - var setCfg = params.setCfg || {}; - if (!setArgs || setArgs.length < 1) { - if (cm) { - showConfirm(cm, 'Invalid mapping: ' + params.input); - } - return; - } - var expr = setArgs[0].split('='); - var optionName = expr[0]; - var value = expr[1]; - var forceGet = false; - - if (optionName.charAt(optionName.length - 1) == '?') { - // If post-fixed with ?, then the set is actually a get. - if (value) { throw Error('Trailing characters: ' + params.argString); } - optionName = optionName.substring(0, optionName.length - 1); - forceGet = true; - } - if (value === undefined && optionName.substring(0, 2) == 'no') { - // To set boolean options to false, the option name is prefixed with - // 'no'. - optionName = optionName.substring(2); - value = false; - } - - var optionIsBoolean = options[optionName] && options[optionName].type == 'boolean'; - if (optionIsBoolean && value == undefined) { - // Calling set with a boolean option sets it to true. - value = true; - } - // If no value is provided, then we assume this is a get. - if (!optionIsBoolean && value === undefined || forceGet) { - var oldValue = getOption(optionName, cm, setCfg); - if (oldValue instanceof Error) { - showConfirm(cm, oldValue.message); - } else if (oldValue === true || oldValue === false) { - showConfirm(cm, ' ' + (oldValue ? '' : 'no') + optionName); - } else { - showConfirm(cm, ' ' + optionName + '=' + oldValue); - } - } else { - var setOptionReturn = setOption(optionName, value, cm, setCfg); - if (setOptionReturn instanceof Error) { - showConfirm(cm, setOptionReturn.message); - } - } - }, - setlocal: function (cm, params) { - // setCfg is passed through to setOption - params.setCfg = {scope: 'local'}; - this.set(cm, params); - }, - setglobal: function (cm, params) { - // setCfg is passed through to setOption - params.setCfg = {scope: 'global'}; - this.set(cm, params); - }, - registers: function(cm, params) { - var regArgs = params.args; - var registers = vimGlobalState.registerController.registers; - var regInfo = '----------Registers----------

      '; - if (!regArgs) { - for (var registerName in registers) { - var text = registers[registerName].toString(); - if (text.length) { - regInfo += '"' + registerName + ' ' + text + '
      '; - } - } - } else { - var registerName; - regArgs = regArgs.join(''); - for (var i = 0; i < regArgs.length; i++) { - registerName = regArgs.charAt(i); - if (!vimGlobalState.registerController.isValidRegister(registerName)) { - continue; - } - var register = registers[registerName] || new Register(); - regInfo += '"' + registerName + ' ' + register.toString() + '
      '; - } - } - showConfirm(cm, regInfo); - }, - sort: function(cm, params) { - var reverse, ignoreCase, unique, number, pattern; - function parseArgs() { - if (params.argString) { - var args = new CodeMirror.StringStream(params.argString); - if (args.eat('!')) { reverse = true; } - if (args.eol()) { return; } - if (!args.eatSpace()) { return 'Invalid arguments'; } - var opts = args.match(/([dinuox]+)?\s*(\/.+\/)?\s*/); - if (!opts && !args.eol()) { return 'Invalid arguments'; } - if (opts[1]) { - ignoreCase = opts[1].indexOf('i') != -1; - unique = opts[1].indexOf('u') != -1; - var decimal = opts[1].indexOf('d') != -1 || opts[1].indexOf('n') != -1 && 1; - var hex = opts[1].indexOf('x') != -1 && 1; - var octal = opts[1].indexOf('o') != -1 && 1; - if (decimal + hex + octal > 1) { return 'Invalid arguments'; } - number = decimal && 'decimal' || hex && 'hex' || octal && 'octal'; - } - if (opts[2]) { - pattern = new RegExp(opts[2].substr(1, opts[2].length - 2), ignoreCase ? 'i' : ''); - } - } - } - var err = parseArgs(); - if (err) { - showConfirm(cm, err + ': ' + params.argString); - return; - } - var lineStart = params.line || cm.firstLine(); - var lineEnd = params.lineEnd || params.line || cm.lastLine(); - if (lineStart == lineEnd) { return; } - var curStart = Pos(lineStart, 0); - var curEnd = Pos(lineEnd, lineLength(cm, lineEnd)); - var text = cm.getRange(curStart, curEnd).split('\n'); - var numberRegex = pattern ? pattern : - (number == 'decimal') ? /(-?)([\d]+)/ : - (number == 'hex') ? /(-?)(?:0x)?([0-9a-f]+)/i : - (number == 'octal') ? /([0-7]+)/ : null; - var radix = (number == 'decimal') ? 10 : (number == 'hex') ? 16 : (number == 'octal') ? 8 : null; - var numPart = [], textPart = []; - if (number || pattern) { - for (var i = 0; i < text.length; i++) { - var matchPart = pattern ? text[i].match(pattern) : null; - if (matchPart && matchPart[0] != '') { - numPart.push(matchPart); - } else if (!pattern && numberRegex.exec(text[i])) { - numPart.push(text[i]); - } else { - textPart.push(text[i]); - } - } - } else { - textPart = text; - } - function compareFn(a, b) { - if (reverse) { var tmp; tmp = a; a = b; b = tmp; } - if (ignoreCase) { a = a.toLowerCase(); b = b.toLowerCase(); } - var anum = number && numberRegex.exec(a); - var bnum = number && numberRegex.exec(b); - if (!anum) { return a < b ? -1 : 1; } - anum = parseInt((anum[1] + anum[2]).toLowerCase(), radix); - bnum = parseInt((bnum[1] + bnum[2]).toLowerCase(), radix); - return anum - bnum; - } - function comparePatternFn(a, b) { - if (reverse) { var tmp; tmp = a; a = b; b = tmp; } - if (ignoreCase) { a[0] = a[0].toLowerCase(); b[0] = b[0].toLowerCase(); } - return (a[0] < b[0]) ? -1 : 1; - } - numPart.sort(pattern ? comparePatternFn : compareFn); - if (pattern) { - for (var i = 0; i < numPart.length; i++) { - numPart[i] = numPart[i].input; - } - } else if (!number) { textPart.sort(compareFn); } - text = (!reverse) ? textPart.concat(numPart) : numPart.concat(textPart); - if (unique) { // Remove duplicate lines - var textOld = text; - var lastLine; - text = []; - for (var i = 0; i < textOld.length; i++) { - if (textOld[i] != lastLine) { - text.push(textOld[i]); - } - lastLine = textOld[i]; - } - } - cm.replaceRange(text.join('\n'), curStart, curEnd); - }, - global: function(cm, params) { - // a global command is of the form - // :[range]g/pattern/[cmd] - // argString holds the string /pattern/[cmd] - var argString = params.argString; - if (!argString) { - showConfirm(cm, 'Regular Expression missing from global'); - return; - } - // range is specified here - var lineStart = (params.line !== undefined) ? params.line : cm.firstLine(); - var lineEnd = params.lineEnd || params.line || cm.lastLine(); - // get the tokens from argString - var tokens = splitBySlash(argString); - var regexPart = argString, cmd; - if (tokens.length) { - regexPart = tokens[0]; - cmd = tokens.slice(1, tokens.length).join('/'); - } - if (regexPart) { - // If regex part is empty, then use the previous query. Otherwise - // use the regex part as the new query. - try { - updateSearchQuery(cm, regexPart, true /** ignoreCase */, - true /** smartCase */); - } catch (e) { - showConfirm(cm, 'Invalid regex: ' + regexPart); - return; - } - } - // now that we have the regexPart, search for regex matches in the - // specified range of lines - var query = getSearchState(cm).getQuery(); - var matchedLines = [], content = ''; - for (var i = lineStart; i <= lineEnd; i++) { - var matched = query.test(cm.getLine(i)); - if (matched) { - matchedLines.push(i+1); - content+= cm.getLine(i) + '
      '; - } - } - // if there is no [cmd], just display the list of matched lines - if (!cmd) { - showConfirm(cm, content); - return; - } - var index = 0; - var nextCommand = function() { - if (index < matchedLines.length) { - var command = matchedLines[index] + cmd; - exCommandDispatcher.processCommand(cm, command, { - callback: nextCommand - }); - } - index++; - }; - nextCommand(); - }, - substitute: function(cm, params) { - if (!cm.getSearchCursor) { - throw new Error('Search feature not available. Requires searchcursor.js or ' + - 'any other getSearchCursor implementation.'); - } - var argString = params.argString; - var tokens = argString ? splitBySeparator(argString, argString[0]) : []; - var regexPart, replacePart = '', trailing, flagsPart, count; - var confirm = false; // Whether to confirm each replace. - var global = false; // True to replace all instances on a line, false to replace only 1. - if (tokens.length) { - regexPart = tokens[0]; - replacePart = tokens[1]; - if (regexPart && regexPart[regexPart.length - 1] === '$') { - regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n'; - replacePart = replacePart ? replacePart + '\n' : '\n'; - } - if (replacePart !== undefined) { - if (getOption('pcre')) { - replacePart = unescapeRegexReplace(replacePart); - } else { - replacePart = translateRegexReplace(replacePart); - } - vimGlobalState.lastSubstituteReplacePart = replacePart; - } - trailing = tokens[2] ? tokens[2].split(' ') : []; - } else { - // either the argString is empty or its of the form ' hello/world' - // actually splitBySlash returns a list of tokens - // only if the string starts with a '/' - if (argString && argString.length) { - showConfirm(cm, 'Substitutions should be of the form ' + - ':s/pattern/replace/'); - return; - } - } - // After the 3rd slash, we can have flags followed by a space followed - // by count. - if (trailing) { - flagsPart = trailing[0]; - count = parseInt(trailing[1]); - if (flagsPart) { - if (flagsPart.indexOf('c') != -1) { - confirm = true; - flagsPart.replace('c', ''); - } - if (flagsPart.indexOf('g') != -1) { - global = true; - flagsPart.replace('g', ''); - } - regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart; - } - } - if (regexPart) { - // If regex part is empty, then use the previous query. Otherwise use - // the regex part as the new query. - try { - updateSearchQuery(cm, regexPart, true /** ignoreCase */, - true /** smartCase */); - } catch (e) { - showConfirm(cm, 'Invalid regex: ' + regexPart); - return; - } - } - replacePart = replacePart || vimGlobalState.lastSubstituteReplacePart; - if (replacePart === undefined) { - showConfirm(cm, 'No previous substitute regular expression'); - return; - } - var state = getSearchState(cm); - var query = state.getQuery(); - var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line; - var lineEnd = params.lineEnd || lineStart; - if (lineStart == cm.firstLine() && lineEnd == cm.lastLine()) { - lineEnd = Infinity; - } - if (count) { - lineStart = lineEnd; - lineEnd = lineStart + count - 1; - } - var startPos = clipCursorToContent(cm, Pos(lineStart, 0)); - var cursor = cm.getSearchCursor(query, startPos); - doReplace(cm, confirm, global, lineStart, lineEnd, cursor, query, replacePart, params.callback); - }, - redo: CodeMirror.commands.redo, - undo: CodeMirror.commands.undo, - write: function(cm) { - if (CodeMirror.commands.save) { - // If a save command is defined, call it. - CodeMirror.commands.save(cm); - } else if (cm.save) { - // Saves to text area if no save command is defined and cm.save() is available. - cm.save(); - } - }, - nohlsearch: function(cm) { - clearSearchHighlight(cm); - }, - yank: function (cm) { - var cur = copyCursor(cm.getCursor()); - var line = cur.line; - var lineText = cm.getLine(line); - vimGlobalState.registerController.pushText( - '0', 'yank', lineText, true, true); - }, - delmarks: function(cm, params) { - if (!params.argString || !trim(params.argString)) { - showConfirm(cm, 'Argument required'); - return; - } - - var state = cm.state.vim; - var stream = new CodeMirror.StringStream(trim(params.argString)); - while (!stream.eol()) { - stream.eatSpace(); - - // Record the streams position at the beginning of the loop for use - // in error messages. - var count = stream.pos; - - if (!stream.match(/[a-zA-Z]/, false)) { - showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); - return; - } - - var sym = stream.next(); - // Check if this symbol is part of a range - if (stream.match('-', true)) { - // This symbol is part of a range. - - // The range must terminate at an alphabetic character. - if (!stream.match(/[a-zA-Z]/, false)) { - showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); - return; - } - - var startMark = sym; - var finishMark = stream.next(); - // The range must terminate at an alphabetic character which - // shares the same case as the start of the range. - if (isLowerCase(startMark) && isLowerCase(finishMark) || - isUpperCase(startMark) && isUpperCase(finishMark)) { - var start = startMark.charCodeAt(0); - var finish = finishMark.charCodeAt(0); - if (start >= finish) { - showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); - return; - } - - // Because marks are always ASCII values, and we have - // determined that they are the same case, we can use - // their char codes to iterate through the defined range. - for (var j = 0; j <= finish - start; j++) { - var mark = String.fromCharCode(start + j); - delete state.marks[mark]; - } - } else { - showConfirm(cm, 'Invalid argument: ' + startMark + '-'); - return; - } - } else { - // This symbol is a valid mark, and is not part of a range. - delete state.marks[sym]; - } - } - } - }; - - var exCommandDispatcher = new ExCommandDispatcher(); - - /** - * @param {CodeMirror} cm CodeMirror instance we are in. - * @param {boolean} confirm Whether to confirm each replace. - * @param {Cursor} lineStart Line to start replacing from. - * @param {Cursor} lineEnd Line to stop replacing at. - * @param {RegExp} query Query for performing matches with. - * @param {string} replaceWith Text to replace matches with. May contain $1, - * $2, etc for replacing captured groups using Javascript replace. - * @param {function()} callback A callback for when the replace is done. - */ - function doReplace(cm, confirm, global, lineStart, lineEnd, searchCursor, query, - replaceWith, callback) { - // Set up all the functions. - cm.state.vim.exMode = true; - var done = false; - var lastPos = searchCursor.from(); - function replaceAll() { - cm.operation(function() { - while (!done) { - replace(); - next(); - } - stop(); - }); - } - function replace() { - var text = cm.getRange(searchCursor.from(), searchCursor.to()); - var newText = text.replace(query, replaceWith); - searchCursor.replace(newText); - } - function next() { - // The below only loops to skip over multiple occurrences on the same - // line when 'global' is not true. - while(searchCursor.findNext() && - isInRange(searchCursor.from(), lineStart, lineEnd)) { - if (!global && lastPos && searchCursor.from().line == lastPos.line) { - continue; - } - cm.scrollIntoView(searchCursor.from(), 30); - cm.setSelection(searchCursor.from(), searchCursor.to()); - lastPos = searchCursor.from(); - done = false; - return; - } - done = true; - } - function stop(close) { - if (close) { close(); } - cm.focus(); - if (lastPos) { - cm.setCursor(lastPos); - var vim = cm.state.vim; - vim.exMode = false; - vim.lastHPos = vim.lastHSPos = lastPos.ch; - } - if (callback) { callback(); } - } - function onPromptKeyDown(e, _value, close) { - // Swallow all keys. - CodeMirror.e_stop(e); - var keyName = CodeMirror.keyName(e); - switch (keyName) { - case 'Y': - replace(); next(); break; - case 'N': - next(); break; - case 'A': - // replaceAll contains a call to close of its own. We don't want it - // to fire too early or multiple times. - var savedCallback = callback; - callback = undefined; - cm.operation(replaceAll); - callback = savedCallback; - break; - case 'L': - replace(); - // fall through and exit. - case 'Q': - case 'Esc': - case 'Ctrl-C': - case 'Ctrl-[': - stop(close); - break; - } - if (done) { stop(close); } - return true; - } - - // Actually do replace. - next(); - if (done) { - showConfirm(cm, 'No matches for ' + query.source); - return; - } - if (!confirm) { - replaceAll(); - if (callback) { callback(); } - return; - } - showPrompt(cm, { - prefix: 'replace with ' + replaceWith + ' (y/n/a/q/l)', - onKeyDown: onPromptKeyDown - }); - } - - CodeMirror.keyMap.vim = { - attach: attachVimMap, - detach: detachVimMap, - call: cmKey - }; - - function exitInsertMode(cm) { - var vim = cm.state.vim; - var macroModeState = vimGlobalState.macroModeState; - var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.'); - var isPlaying = macroModeState.isPlaying; - var lastChange = macroModeState.lastInsertModeChanges; - // In case of visual block, the insertModeChanges are not saved as a - // single word, so we convert them to a single word - // so as to update the ". register as expected in real vim. - var text = []; - if (!isPlaying) { - var selLength = lastChange.inVisualBlock && vim.lastSelection ? - vim.lastSelection.visualBlock.height : 1; - var changes = lastChange.changes; - var text = []; - var i = 0; - // In case of multiple selections in blockwise visual, - // the inserted text, for example: 'foo', is stored as - // 'f', 'f', InsertModeKey 'o', 'o', 'o', 'o'. (if you have a block with 2 lines). - // We push the contents of the changes array as per the following: - // 1. In case of InsertModeKey, just increment by 1. - // 2. In case of a character, jump by selLength (2 in the example). - while (i < changes.length) { - // This loop will convert 'ffoooo' to 'foo'. - text.push(changes[i]); - if (changes[i] instanceof InsertModeKey) { - i++; - } else { - i+= selLength; - } - } - lastChange.changes = text; - cm.off('change', onChange); - CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown); - } - if (!isPlaying && vim.insertModeRepeat > 1) { - // Perform insert mode repeat for commands like 3,a and 3,o. - repeatLastEdit(cm, vim, vim.insertModeRepeat - 1, - true /** repeatForInsert */); - vim.lastEditInputState.repeatOverride = vim.insertModeRepeat; - } - delete vim.insertModeRepeat; - vim.insertMode = false; - cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1); - cm.setOption('keyMap', 'vim'); - cm.setOption('disableInput', true); - cm.toggleOverwrite(false); // exit replace mode if we were in it. - // update the ". register before exiting insert mode - insertModeChangeRegister.setText(lastChange.changes.join('')); - CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); - if (macroModeState.isRecording) { - logInsertModeChange(macroModeState); - } - } - - function _mapCommand(command) { - defaultKeymap.unshift(command); - } - - function mapCommand(keys, type, name, args, extra) { - var command = {keys: keys, type: type}; - command[type] = name; - command[type + "Args"] = args; - for (var key in extra) - command[key] = extra[key]; - _mapCommand(command); - } - - // The timeout in milliseconds for the two-character ESC keymap should be - // adjusted according to your typing speed to prevent false positives. - defineOption('insertModeEscKeysTimeout', 200, 'number'); - - CodeMirror.keyMap['vim-insert'] = { - // TODO: override navigation keys so that Esc will cancel automatic - // indentation from o, O, i_ - 'Ctrl-N': 'autocomplete', - 'Ctrl-P': 'autocomplete', - 'Enter': function(cm) { - var fn = CodeMirror.commands.newlineAndIndentContinueComment || - CodeMirror.commands.newlineAndIndent; - fn(cm); - }, - fallthrough: ['default'], - attach: attachVimMap, - detach: detachVimMap, - call: cmKey - }; - - CodeMirror.keyMap['vim-replace'] = { - 'Backspace': 'goCharLeft', - fallthrough: ['vim-insert'], - attach: attachVimMap, - detach: detachVimMap, - call: cmKey - }; - - function executeMacroRegister(cm, vim, macroModeState, registerName) { - var register = vimGlobalState.registerController.getRegister(registerName); - if (registerName == ':') { - // Read-only register containing last Ex command. - if (register.keyBuffer[0]) { - exCommandDispatcher.processCommand(cm, register.keyBuffer[0]); - } - macroModeState.isPlaying = false; - return; - } - var keyBuffer = register.keyBuffer; - var imc = 0; - macroModeState.isPlaying = true; - macroModeState.replaySearchQueries = register.searchQueries.slice(0); - for (var i = 0; i < keyBuffer.length; i++) { - var text = keyBuffer[i]; - var match, key; - while (text) { - // Pull off one command key, which is either a single character - // or a special sequence wrapped in '<' and '>', e.g. ''. - match = (/<\w+-.+?>|<\w+>|./).exec(text); - key = match[0]; - text = text.substring(match.index + key.length); - CodeMirror.Vim.handleKey(cm, key, 'macro'); - if (vim.insertMode) { - var changes = register.insertModeChanges[imc++].changes; - vimGlobalState.macroModeState.lastInsertModeChanges.changes = - changes; - repeatInsertModeChanges(cm, changes, 1); - exitInsertMode(cm); - } - } - } - macroModeState.isPlaying = false; - } - - function logKey(macroModeState, key) { - if (macroModeState.isPlaying) { return; } - var registerName = macroModeState.latestRegister; - var register = vimGlobalState.registerController.getRegister(registerName); - if (register) { - register.pushText(key); - } - } - - function logInsertModeChange(macroModeState) { - if (macroModeState.isPlaying) { return; } - var registerName = macroModeState.latestRegister; - var register = vimGlobalState.registerController.getRegister(registerName); - if (register && register.pushInsertModeChanges) { - register.pushInsertModeChanges(macroModeState.lastInsertModeChanges); - } - } - - function logSearchQuery(macroModeState, query) { - if (macroModeState.isPlaying) { return; } - var registerName = macroModeState.latestRegister; - var register = vimGlobalState.registerController.getRegister(registerName); - if (register && register.pushSearchQuery) { - register.pushSearchQuery(query); - } - } - - /** - * Listens for changes made in insert mode. - * Should only be active in insert mode. - */ - function onChange(cm, changeObj) { - var macroModeState = vimGlobalState.macroModeState; - var lastChange = macroModeState.lastInsertModeChanges; - if (!macroModeState.isPlaying) { - while(changeObj) { - lastChange.expectCursorActivityForChange = true; - if (changeObj.origin == '+input' || changeObj.origin == 'paste' - || changeObj.origin === undefined /* only in testing */) { - var text = changeObj.text.join('\n'); - if (lastChange.maybeReset) { - lastChange.changes = []; - lastChange.maybeReset = false; - } - if (cm.state.overwrite && !/\n/.test(text)) { - lastChange.changes.push([text]); - } else { - lastChange.changes.push(text); - } - } - // Change objects may be chained with next. - changeObj = changeObj.next; - } - } - } - - /** - * Listens for any kind of cursor activity on CodeMirror. - */ - function onCursorActivity(cm) { - var vim = cm.state.vim; - if (vim.insertMode) { - // Tracking cursor activity in insert mode (for macro support). - var macroModeState = vimGlobalState.macroModeState; - if (macroModeState.isPlaying) { return; } - var lastChange = macroModeState.lastInsertModeChanges; - if (lastChange.expectCursorActivityForChange) { - lastChange.expectCursorActivityForChange = false; - } else { - // Cursor moved outside the context of an edit. Reset the change. - lastChange.maybeReset = true; - } - } else if (!cm.curOp.isVimOp) { - handleExternalSelection(cm, vim); - } - if (vim.visualMode) { - updateFakeCursor(cm); - } - } - function updateFakeCursor(cm) { - var vim = cm.state.vim; - var from = clipCursorToContent(cm, copyCursor(vim.sel.head)); - var to = offsetCursor(from, 0, 1); - if (vim.fakeCursor) { - vim.fakeCursor.clear(); - } - vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'}); - } - function handleExternalSelection(cm, vim) { - var anchor = cm.getCursor('anchor'); - var head = cm.getCursor('head'); - // Enter or exit visual mode to match mouse selection. - if (vim.visualMode && !cm.somethingSelected()) { - exitVisualMode(cm, false); - } else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) { - vim.visualMode = true; - vim.visualLine = false; - CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"}); - } - if (vim.visualMode) { - // Bind CodeMirror selection model to vim selection model. - // Mouse selections are considered visual characterwise. - var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0; - var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0; - head = offsetCursor(head, 0, headOffset); - anchor = offsetCursor(anchor, 0, anchorOffset); - vim.sel = { - anchor: anchor, - head: head - }; - updateMark(cm, vim, '<', cursorMin(head, anchor)); - updateMark(cm, vim, '>', cursorMax(head, anchor)); - } else if (!vim.insertMode) { - // Reset lastHPos if selection was modified by something outside of vim mode e.g. by mouse. - vim.lastHPos = cm.getCursor().ch; - } - } - - /** Wrapper for special keys pressed in insert mode */ - function InsertModeKey(keyName) { - this.keyName = keyName; - } - - /** - * Handles raw key down events from the text area. - * - Should only be active in insert mode. - * - For recording deletes in insert mode. - */ - function onKeyEventTargetKeyDown(e) { - var macroModeState = vimGlobalState.macroModeState; - var lastChange = macroModeState.lastInsertModeChanges; - var keyName = CodeMirror.keyName(e); - if (!keyName) { return; } - function onKeyFound() { - if (lastChange.maybeReset) { - lastChange.changes = []; - lastChange.maybeReset = false; - } - lastChange.changes.push(new InsertModeKey(keyName)); - return true; - } - if (keyName.indexOf('Delete') != -1 || keyName.indexOf('Backspace') != -1) { - CodeMirror.lookupKey(keyName, 'vim-insert', onKeyFound); - } - } - - /** - * Repeats the last edit, which includes exactly 1 command and at most 1 - * insert. Operator and motion commands are read from lastEditInputState, - * while action commands are read from lastEditActionCommand. - * - * If repeatForInsert is true, then the function was called by - * exitInsertMode to repeat the insert mode changes the user just made. The - * corresponding enterInsertMode call was made with a count. - */ - function repeatLastEdit(cm, vim, repeat, repeatForInsert) { - var macroModeState = vimGlobalState.macroModeState; - macroModeState.isPlaying = true; - var isAction = !!vim.lastEditActionCommand; - var cachedInputState = vim.inputState; - function repeatCommand() { - if (isAction) { - commandDispatcher.processAction(cm, vim, vim.lastEditActionCommand); - } else { - commandDispatcher.evalInput(cm, vim); - } - } - function repeatInsert(repeat) { - if (macroModeState.lastInsertModeChanges.changes.length > 0) { - // For some reason, repeat cw in desktop VIM does not repeat - // insert mode changes. Will conform to that behavior. - repeat = !vim.lastEditActionCommand ? 1 : repeat; - var changeObject = macroModeState.lastInsertModeChanges; - repeatInsertModeChanges(cm, changeObject.changes, repeat); - } - } - vim.inputState = vim.lastEditInputState; - if (isAction && vim.lastEditActionCommand.interlaceInsertRepeat) { - // o and O repeat have to be interlaced with insert repeats so that the - // insertions appear on separate lines instead of the last line. - for (var i = 0; i < repeat; i++) { - repeatCommand(); - repeatInsert(1); - } - } else { - if (!repeatForInsert) { - // Hack to get the cursor to end up at the right place. If I is - // repeated in insert mode repeat, cursor will be 1 insert - // change set left of where it should be. - repeatCommand(); - } - repeatInsert(repeat); - } - vim.inputState = cachedInputState; - if (vim.insertMode && !repeatForInsert) { - // Don't exit insert mode twice. If repeatForInsert is set, then we - // were called by an exitInsertMode call lower on the stack. - exitInsertMode(cm); - } - macroModeState.isPlaying = false; - } - - function repeatInsertModeChanges(cm, changes, repeat) { - function keyHandler(binding) { - if (typeof binding == 'string') { - CodeMirror.commands[binding](cm); - } else { - binding(cm); - } - return true; - } - var head = cm.getCursor('head'); - var inVisualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock; - if (inVisualBlock) { - // Set up block selection again for repeating the changes. - var vim = cm.state.vim; - var lastSel = vim.lastSelection; - var offset = getOffset(lastSel.anchor, lastSel.head); - selectForInsert(cm, head, offset.line + 1); - repeat = cm.listSelections().length; - cm.setCursor(head); - } - for (var i = 0; i < repeat; i++) { - if (inVisualBlock) { - cm.setCursor(offsetCursor(head, i, 0)); - } - for (var j = 0; j < changes.length; j++) { - var change = changes[j]; - if (change instanceof InsertModeKey) { - CodeMirror.lookupKey(change.keyName, 'vim-insert', keyHandler); - } else if (typeof change == "string") { - var cur = cm.getCursor(); - cm.replaceRange(change, cur, cur); - } else { - var start = cm.getCursor(); - var end = offsetCursor(start, 0, change[0].length); - cm.replaceRange(change[0], start, end); - } - } - } - if (inVisualBlock) { - cm.setCursor(offsetCursor(head, 0, 1)); - } - } - - resetVimGlobalState(); - //}; - // Initialize Vim and make it available as an API. - CodeMirror.Vim = Vim(); - - Vim = CodeMirror.Vim; - - var specialKey = {'return':'CR',backspace:'BS','delete':'Del',esc:'Esc', - left:'Left',right:'Right',up:'Up',down:'Down',space: 'Space', - home:'Home',end:'End',pageup:'PageUp',pagedown:'PageDown', enter: 'CR' - }; - function lookupKey(hashId, key, e) { - if (key.length > 1 && key[0] == "n") { - key = key.replace("numpad", ""); - } - key = specialKey[key] || key; - var name = ''; - if (e.ctrlKey) { name += 'C-'; } - if (e.altKey) { name += 'A-'; } - if ((name || key.length > 1) && e.shiftKey) { name += 'S-'; } - - name += key; - if (name.length > 1) { name = '<' + name + '>'; } - return name; - } - var handleKey = Vim.handleKey.bind(Vim); - Vim.handleKey = function(cm, key, origin) { - return cm.operation(function() { - return handleKey(cm, key, origin); - }, true); - } - function cloneVimState(state) { - var n = new state.constructor(); - Object.keys(state).forEach(function(key) { - var o = state[key]; - if (Array.isArray(o)) - o = o.slice(); - else if (o && typeof o == "object" && o.constructor != Object) - o = cloneVimState(o); - n[key] = o; - }); - if (state.sel) { - n.sel = { - head: state.sel.head && copyCursor(state.sel.head), - anchor: state.sel.anchor && copyCursor(state.sel.anchor) - }; - } - return n; - } - function multiSelectHandleKey(cm, key, origin) { - var isHandled = false; - var vim = Vim.maybeInitVimState_(cm); - var visualBlock = vim.visualBlock || vim.wasInVisualBlock; - if (vim.wasInVisualBlock && !cm.ace.inMultiSelectMode) { - vim.wasInVisualBlock = false; - } else if (cm.ace.inMultiSelectMode && vim.visualBlock) { - vim.wasInVisualBlock = true; - } - - if (key == '' && !vim.insertMode && !vim.visualMode && cm.ace.inMultiSelectMode) { - cm.ace.exitMultiSelectMode(); - } else if (visualBlock || !cm.ace.inMultiSelectMode || cm.ace.inVirtualSelectionMode) { - isHandled = Vim.handleKey(cm, key, origin); - } else { - var old = cloneVimState(vim); - cm.operation(function() { - cm.ace.forEachSelection(function() { - var sel = cm.ace.selection; - cm.state.vim.lastHPos = sel.$desiredColumn == null ? sel.lead.column : sel.$desiredColumn; - var head = cm.getCursor("head"); - var anchor = cm.getCursor("anchor"); - var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0; - var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0; - head = offsetCursor(head, 0, headOffset); - anchor = offsetCursor(anchor, 0, anchorOffset); - cm.state.vim.sel.head = head; - cm.state.vim.sel.anchor = anchor; - - isHandled = handleKey(cm, key, origin); - sel.$desiredColumn = cm.state.vim.lastHPos == -1 ? null : cm.state.vim.lastHPos; - if (cm.virtualSelectionMode()) { - cm.state.vim = cloneVimState(old); - } - }); - if (cm.curOp.cursorActivity && !isHandled) - cm.curOp.cursorActivity = false; - }, true); - } - return isHandled; - } - exports.CodeMirror = CodeMirror; - var getVim = Vim.maybeInitVimState_; - exports.handler = { - $id: "ace/keyboard/vim", - drawCursor: function(element, pixelPos, config, sel, session) { - var vim = this.state.vim || {}; - var w = config.characterWidth; - var h = config.lineHeight; - var top = pixelPos.top; - var left = pixelPos.left; - if (!vim.insertMode) { - var isbackwards = !sel.cursor - ? session.selection.isBackwards() || session.selection.isEmpty() - : Range.comparePoints(sel.cursor, sel.start) <= 0; - if (!isbackwards && left > w) - left -= w; - } - if (!vim.insertMode && vim.status) { - h = h / 2; - top += h; - } - dom.translate(element, left, top); - dom.setStyle(element.style, "width", w + "px"); - dom.setStyle(element.style, "height", h + "px"); - }, - handleKeyboard: function(data, hashId, key, keyCode, e) { - var editor = data.editor; - var cm = editor.state.cm; - var vim = getVim(cm); - if (keyCode == -1) return; - - // in non-insert mode we try to find the ascii key corresponding to the text in textarea - // this is needed because in languages that use latin alphabet we want to get the key that browser sends to the textarea - // and in non - if (!vim.insertMode) { - if (hashId == -1) { - if (key.charCodeAt(0) > 0xFF) { - if (data.inputKey) { - key = data.inputKey; - if (key && data.inputHash == 4) - key = key.toUpperCase(); - } - } - data.inputChar = key; - } - else if (hashId == 4 || hashId == 0) { - if (data.inputKey == key && data.inputHash == hashId && data.inputChar) { - // on mac text input doesn't repeat - key = data.inputChar; - hashId = -1 - } - else { - data.inputChar = null; - data.inputKey = key; - data.inputHash = hashId; - } - } - else { - data.inputChar = data.inputKey = null; - } - } - - // ctrl-c is special it both exits mode and copies text - if (key == "c" && hashId == 1) { // key == "ctrl-c" - if (!useragent.isMac && editor.getCopyText()) { - editor.once("copy", function() { - editor.selection.clearSelection(); - }); - return {command: "null", passEvent: true}; - } - } - - if (key == "esc" && !vim.insertMode && !vim.visualMode && !cm.ace.inMultiSelectMode) { - var searchState = getSearchState(cm); - var overlay = searchState.getOverlay(); - if (overlay) cm.removeOverlay(overlay); - } - - if (hashId == -1 || hashId & 1 || hashId === 0 && key.length > 1) { - var insertMode = vim.insertMode; - var name = lookupKey(hashId, key, e || {}); - if (vim.status == null) - vim.status = ""; - var isHandled = multiSelectHandleKey(cm, name, 'user'); - vim = getVim(cm); // may be changed by multiSelectHandleKey - if (isHandled && vim.status != null) - vim.status += name; - else if (vim.status == null) - vim.status = ""; - cm._signal("changeStatus"); - if (!isHandled && (hashId != -1 || insertMode)) - return; - return {command: "null", passEvent: !isHandled}; - } - }, - attach: function(editor) { - if (!editor.state) editor.state = {}; - var cm = new CodeMirror(editor); - editor.state.cm = cm; - editor.$vimModeHandler = this; - CodeMirror.keyMap.vim.attach(cm); - getVim(cm).status = null; - cm.on('vim-command-done', function() { - if (cm.virtualSelectionMode()) return; - getVim(cm).status = null; - cm.ace._signal("changeStatus"); - cm.ace.session.markUndoGroup(); - }); - cm.on("changeStatus", function() { - cm.ace.renderer.updateCursor(); - cm.ace._signal("changeStatus"); - }); - cm.on("vim-mode-change", function() { - if (cm.virtualSelectionMode()) return; - updateInputMode(); - cm._signal("changeStatus"); - }); - function updateInputMode() { - var isIntsert = getVim(cm).insertMode; - cm.ace.renderer.setStyle("normal-mode", !isIntsert); - editor.textInput.setCommandMode(!isIntsert); - // without this press and hodl popup in mac is shown in normal mode - editor.renderer.$keepTextAreaAtCursor = isIntsert; - editor.renderer.$blockCursor = !isIntsert; - } - updateInputMode(); - editor.renderer.$cursorLayer.drawCursor = this.drawCursor.bind(cm); - this.updateMacCompositionHandlers(editor, true); - }, - detach: function(editor) { - var cm = editor.state.cm; - CodeMirror.keyMap.vim.detach(cm); - cm.destroy(); - editor.state.cm = null; - editor.$vimModeHandler = null; - editor.renderer.$cursorLayer.drawCursor = null; - editor.renderer.setStyle("normal-mode", false); - editor.textInput.setCommandMode(false); - editor.renderer.$keepTextAreaAtCursor = true; - this.updateMacCompositionHandlers(editor, false); - }, - getStatusText: function(editor) { - var cm = editor.state.cm; - var vim = getVim(cm); - if (vim.insertMode) - return "INSERT"; - var status = ""; - if (vim.visualMode) { - status += "VISUAL"; - if (vim.visualLine) - status += " LINE"; - if (vim.visualBlock) - status += " BLOCK"; - } - if (vim.status) - status += (status ? " " : "") + vim.status; - return status; - }, - // on mac, with some keyboard layouts (e.g swedish) ^ starts composition, we don't need it in normal mode - updateMacCompositionHandlers: function(editor, enable) { - var onCompositionUpdateOverride = function(text) { - var cm = editor.state.cm; - var vim = getVim(cm); - if (!vim.insertMode) { - var el = this.textInput.getElement(); - el.blur(); - el.focus(); - el.value = text; - } else { - this.onCompositionUpdateOrig(text); - } - }; - var onCompositionStartOverride = function(text) { - var cm = editor.state.cm; - var vim = getVim(cm); - if (vim.insertMode) { - this.onCompositionStartOrig(text); - } - }; - if (enable) { - if (!editor.onCompositionUpdateOrig) { - editor.onCompositionUpdateOrig = editor.onCompositionUpdate; - editor.onCompositionUpdate = onCompositionUpdateOverride; - editor.onCompositionStartOrig = editor.onCompositionStart; - editor.onCompositionStart = onCompositionStartOverride; - } - } else { - if (editor.onCompositionUpdateOrig) { - editor.onCompositionUpdate = editor.onCompositionUpdateOrig; - editor.onCompositionUpdateOrig = null; - editor.onCompositionStart = editor.onCompositionStartOrig; - editor.onCompositionStartOrig = null; - } - } - } - }; - Vim.defineOption({ - name: "wrap", - set: function(value, cm) { - if (cm) {cm.ace.setOption("wrap", value)} - }, - type: "boolean" - }, false); - Vim.defineEx('write', 'w', function() { - console.log(':write is not implemented') - }); - defaultKeymap.push( - { keys: 'zc', type: 'action', action: 'fold', actionArgs: { open: false } }, - { keys: 'zC', type: 'action', action: 'fold', actionArgs: { open: false, all: true } }, - { keys: 'zo', type: 'action', action: 'fold', actionArgs: { open: true } }, - { keys: 'zO', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, - { keys: 'za', type: 'action', action: 'fold', actionArgs: { toggle: true } }, - { keys: 'zA', type: 'action', action: 'fold', actionArgs: { toggle: true, all: true } }, - { keys: 'zf', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, - { keys: 'zd', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, - - { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAbove" } }, - { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelow" } }, - { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAboveSkipCurrent" } }, - { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelowSkipCurrent" } }, - { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectMoreBefore" } }, - { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectMoreAfter" } }, - { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectNextBefore" } }, - { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectNextAfter" } } - ); - actions.aceCommand = function(cm, actionArgs, vim) { - cm.vimCmd = actionArgs; - if (cm.ace.inVirtualSelectionMode) - cm.ace.on("beforeEndOperation", delayedExecAceCommand); - else - delayedExecAceCommand(null, cm.ace); - }; - function delayedExecAceCommand(op, ace) { - ace.off("beforeEndOperation", delayedExecAceCommand); - var cmd = ace.state.cm.vimCmd; - if (cmd) { - ace.execCommand(cmd.exec ? cmd : cmd.name, cmd.args); - } - ace.curOp = ace.prevOp; - } - actions.fold = function(cm, actionArgs, vim) { - cm.ace.execCommand(['toggleFoldWidget', 'toggleFoldWidget', 'foldOther', 'unfoldall' - ][(actionArgs.all ? 2 : 0) + (actionArgs.open ? 1 : 0)]); - }; - - exports.handler.defaultKeymap = defaultKeymap; - exports.handler.actions = actions; - exports.Vim = Vim; - - Vim.map("Y", "yy", "normal"); -}); diff --git a/lib/ace/keyboard/vim_test.js b/lib/ace/keyboard/vim_test.js deleted file mode 100644 index c64e17f8af8..00000000000 --- a/lib/ace/keyboard/vim_test.js +++ /dev/null @@ -1,4605 +0,0 @@ - -if (typeof process !== "undefined") { - require("amd-loader"); - require("../test/mockdom"); -} - -define(function(require, exports, module) { - -var EditSession = require("./../edit_session").EditSession; -var Editor = require("./../editor").Editor; -var UndoManager = require("./../undomanager").UndoManager; -var MockRenderer = require("./../test/mockrenderer").MockRenderer; -var JavaScriptMode = require("./../mode/javascript").Mode; -var VirtualRenderer = require("./../virtual_renderer").VirtualRenderer; -var assert = require("./../test/assertions"); -var keys = require("./../lib/keys"); -var vim = require("./vim"); -var isAce = true; - -var el = document.createElement("div"); -el.style.position = "fixed"; -el.style.left = "20px"; -el.style.top = "30px"; -el.style.width = "500px"; -el.style.height = "300px"; -document.body.appendChild(el); - -var phantom = window.name == "nodejs"; - -var renderer = new VirtualRenderer(el); -editor = new Editor(renderer);//(new MockRenderer()); -editor.session.setUndoManager(new UndoManager()); -editor.session.setUseWorker(false); -editor.session.setMode(new JavaScriptMode()); -function CodeMirror(place, opts) { - if (opts.value != null) - editor.session.setValue(opts.value); - editor.setOption("indentedSoftWrap", false); - editor.setOption("wrap", opts.lineWrapping); - editor.setOption("useSoftTabs", !opts.indentWithTabs); - editor.setKeyboardHandler(null); - editor.setKeyboardHandler(vim.handler); - var cm = editor.state.cm; - cm.setOption("tabSize", opts.tabSize || 4); - cm.setOption("indentUnit", opts.indentUnit || 2); - - cm.setSize = function(w, h) { - var changed = false; - if (w && editor.w != w) { - changed = true; - el.style.width = (editor.w = w) + "px"; - } - if (h && editor.h != h) { - changed = true; - el.style.height = (editor.h = h) + "px"; - } - if (changed) - editor.resize(true); - }; - cm.setSize(500, 300); - return cm; -} -CodeMirror.defineMode = function() {} -for (var key in vim.CodeMirror) - CodeMirror[key] = vim.CodeMirror[key]; -var editor; -var i = 0; -function test(name, fn) { - // if (name != 'vim_search_history') return - // for (i = 0; i < 1000; i++) - // exports["test " + name + i] = fn; // vim_ex_global_confirm - if (i++ < 0 || /- /.test(name)) - exports["test " + name] = function() {}; - else - exports["test " + name] = fn; -} -function expectFail(fn, silent) { - try { - fn(); - } catch(expected) { - return; - }; - if (!silent) - throw new Error("Expected to throw an error"); -} - -vim.CodeMirror.Vim.unmap("Y"); -vim.CodeMirror.Vim.defineEx('write', 'w', function(cm) { - CodeMirror.commands.save(cm); -}); - - - -// cm.setBookmark({ch: 5, line: 0}) -// cm.setBookmark({ch: 4, line: 0}) -// cm.replaceRange("x-", {ch: 4, line: 0}, {ch: 5, line: 0}); [editor.$vimModeHandler.cm.marks[0].find(),editor.$vimModeHandler.cm.marks[1].find()] - -var lineText, verbose; -var Pos = CodeMirror.Pos; -var place = document.createElement("div"); -var eqCursorPos = assert.deepEqual; -var eq = assert.equal; -var is = assert.ok; - -CodeMirror.Vim.suppressErrorLogging = true; - -var code = '' + -' wOrd1 (#%\n' + -' word3] \n' + -'aopop pop 0 1 2 3 4\n' + -' (a) [b] {c} \n' + -'int getchar(void) {\n' + -' static char buf[BUFSIZ];\n' + -' static char *bufp = buf;\n' + -' if (n == 0) { /* buffer is empty */\n' + -' n = read(0, buf, sizeof buf);\n' + -' bufp = buf;\n' + -' }\n' + -'\n' + -' return (--n >= 0) ? (unsigned char) *bufp++ : EOF;\n' + -' \n' + -'}\n'; - -var lines = (function() { - lineText = code.split('\n'); - var ret = []; - for (var i = 0; i < lineText.length; i++) { - ret[i] = { - line: i, - length: lineText[i].length, - lineText: lineText[i], - textStart: /^\s*/.exec(lineText[i])[0].length - }; - } - return ret; -})(); -var endOfDocument = makeCursor(lines.length - 1, - lines[lines.length - 1].length); -var wordLine = lines[0]; -var bigWordLine = lines[1]; -var charLine = lines[2]; -var bracesLine = lines[3]; -var seekBraceLine = lines[4]; - -var word1 = { - start: new Pos(wordLine.line, 1), - end: new Pos(wordLine.line, 5) -}; -var word2 = { - start: new Pos(wordLine.line, word1.end.ch + 2), - end: new Pos(wordLine.line, word1.end.ch + 4) -}; -var word3 = { - start: new Pos(bigWordLine.line, 1), - end: new Pos(bigWordLine.line, 5) -}; -var bigWord1 = word1; -var bigWord2 = word2; -var bigWord3 = { - start: new Pos(bigWordLine.line, 1), - end: new Pos(bigWordLine.line, 7) -}; -var bigWord4 = { - start: new Pos(bigWordLine.line, bigWord1.end.ch + 3), - end: new Pos(bigWordLine.line, bigWord1.end.ch + 7) -}; - -var oChars = [ new Pos(charLine.line, 1), - new Pos(charLine.line, 3), - new Pos(charLine.line, 7) ]; -var pChars = [ new Pos(charLine.line, 2), - new Pos(charLine.line, 4), - new Pos(charLine.line, 6), - new Pos(charLine.line, 8) ]; -var numChars = [ new Pos(charLine.line, 10), - new Pos(charLine.line, 12), - new Pos(charLine.line, 14), - new Pos(charLine.line, 16), - new Pos(charLine.line, 18)]; -var parens1 = { - start: new Pos(bracesLine.line, 1), - end: new Pos(bracesLine.line, 3) -}; -var squares1 = { - start: new Pos(bracesLine.line, 5), - end: new Pos(bracesLine.line, 7) -}; -var curlys1 = { - start: new Pos(bracesLine.line, 9), - end: new Pos(bracesLine.line, 11) -}; -var seekOutside = { - start: new Pos(seekBraceLine.line, 1), - end: new Pos(seekBraceLine.line, 16) -}; -var seekInside = { - start: new Pos(seekBraceLine.line, 14), - end: new Pos(seekBraceLine.line, 11) -}; - -function copyCursor(cur) { - return new Pos(cur.line, cur.ch); -} - -function forEach(arr, func) { - for (var i = 0; i < arr.length; i++) { - func(arr[i], i, arr); - } -} - -function testVim(name, run, opts, expectedFail) { - var vimOpts = { - lineNumbers: true, - vimMode: true, - showCursorWhenSelecting: true, - value: code - }; - for (var prop in opts) { - if (opts.hasOwnProperty(prop)) { - vimOpts[prop] = opts[prop]; - } - } - return test('vim_' + name, function() { - var place = document.getElementById("testground"); - var cm = CodeMirror(place, vimOpts); - var vim = CodeMirror.Vim.maybeInitVimState_(cm); - - function doKeysFn(cm) { - return function(args) { - if (args instanceof Array) { - arguments = args; - } - for (var i = 0; i < arguments.length; i++) { - var result = CodeMirror.Vim.handleKey(cm, arguments[i]); - if (!result && cm.state.vim.insertMode) { - cm.replaceSelections(fillArray(arguments[i], cm.listSelections().length)); - } - } - } - } - function doInsertModeKeysFn(cm) { - return function(args) { - if (args instanceof Array) { arguments = args; } - function executeHandler(handler) { - if (typeof handler == 'string') { - CodeMirror.commands[handler](cm); - } else { - handler(cm); - } - return true; - } - for (var i = 0; i < arguments.length; i++) { - var key = arguments[i]; - // Find key in keymap and handle. - var handled = CodeMirror.lookupKey(key, cm.getOption('keyMap'), executeHandler, cm); - // Record for insert mode. - if (handled == "handled" && cm.state.vim.insertMode && arguments[i] != 'Esc') { - var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges; - if (lastChange && (key.indexOf('Delete') != -1 || key.indexOf('Backspace') != -1)) { - lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key)); - } - } - } - } - } - function doExFn(cm) { - return function(command) { - cm.openDialog = helpers.fakeOpenDialog(command); - helpers.doKeys(':'); - } - } - function assertCursorAtFn(cm) { - return function(line, ch) { - var pos; - if (ch == null && typeof line.line == 'number') { - pos = line; - } else { - pos = makeCursor(line, ch); - } - eqCursorPos(cm.getCursor(), pos); - } - } - function fakeOpenDialog(result) { - return function(text, callback) { - return callback(result); - } - } - function fakeOpenNotification(matcher) { - return function(text) { - matcher(text); - } - } - var helpers = { - doKeys: doKeysFn(cm), - // Warning: Only emulates keymap events, not character insertions. Use - // replaceRange to simulate character insertions. - // Keys are in CodeMirror format, NOT vim format. - doInsertModeKeys: doInsertModeKeysFn(cm), - doEx: doExFn(cm), - assertCursorAt: assertCursorAtFn(cm), - fakeOpenDialog: fakeOpenDialog, - fakeOpenNotification: fakeOpenNotification, - getRegisterController: function() { - return CodeMirror.Vim.getRegisterController(); - } - } - CodeMirror.Vim.resetVimGlobalState_(); - var successful = false; - var savedOpenNotification = cm.openNotification; - var savedOpenDialog = cm.openDialog; - try { - run(cm, vim, helpers); - successful = true; - } finally { - cm.openNotification = savedOpenNotification; - cm.openDialog = savedOpenDialog; - // ace_patch - } - }); -} -testVim('qq@q', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'q', 'l', 'l', 'q'); - helpers.assertCursorAt(0,2); - helpers.doKeys('@', 'q'); - helpers.assertCursorAt(0,4); -}, { value: ' '}); -testVim('@@', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'q', 'l', 'l', 'q'); - helpers.assertCursorAt(0,2); - helpers.doKeys('@', 'q'); - helpers.assertCursorAt(0,4); - helpers.doKeys('@', '@'); - helpers.assertCursorAt(0,6); -}, { value: ' '}); -var jumplistScene = ''+ - 'word\n'+ - '(word)\n'+ - '{word\n'+ - 'word.\n'+ - '\n'+ - 'word search\n'+ - '}word\n'+ - 'word\n'+ - 'word\n'; -function testJumplist(name, keys, endPos, startPos, dialog) { - endPos = makeCursor(endPos[0], endPos[1]); - startPos = makeCursor(startPos[0], startPos[1]); - testVim(name, function(cm, vim, helpers) { - CodeMirror.Vim.resetVimGlobalState_(); - if(dialog)cm.openDialog = helpers.fakeOpenDialog('word'); - cm.setCursor(startPos); - helpers.doKeys.apply(null, keys); - helpers.assertCursorAt(endPos); - }, {value: jumplistScene}); -} -testJumplist('jumplist_H', ['H', ''], [5,2], [5,2]); -testJumplist('jumplist_M', ['M', ''], [2,2], [2,2]); -testJumplist('jumplist_L', ['L', ''], [2,2], [2,2]); -testJumplist('jumplist_[[', ['[', '[', ''], [5,2], [5,2]); -testJumplist('jumplist_]]', [']', ']', ''], [2,2], [2,2]); -testJumplist('jumplist_G', ['G', ''], [5,2], [5,2]); -testJumplist('jumplist_gg', ['g', 'g', ''], [5,2], [5,2]); -testJumplist('jumplist_%', ['%', ''], [1,5], [1,5]); -testJumplist('jumplist_{', ['{', ''], [1,5], [1,5]); -testJumplist('jumplist_}', ['}', ''], [1,5], [1,5]); -testJumplist('jumplist_\'', ['m', 'a', 'h', '\'', 'a', 'h', ''], [1,0], [1,5]); -testJumplist('jumplist_`', ['m', 'a', 'h', '`', 'a', 'h', ''], [1,5], [1,5]); -testJumplist('jumplist_*_cachedCursor', ['*', ''], [1,3], [1,3]); -testJumplist('jumplist_#_cachedCursor', ['#', ''], [1,3], [1,3]); -testJumplist('jumplist_n', ['#', 'n', ''], [1,1], [2,3]); -testJumplist('jumplist_N', ['#', 'N', ''], [1,1], [2,3]); -testJumplist('jumplist_repeat_', ['*', '*', '*', '3', ''], [2,3], [2,3]); -testJumplist('jumplist_repeat_', ['*', '*', '*', '3', '', '2', ''], [5,0], [2,3]); -testJumplist('jumplist_repeated_motion', ['3', '*', ''], [2,3], [2,3]); -testJumplist('jumplist_/', ['/', ''], [2,3], [2,3], 'dialog'); -testJumplist('jumplist_?', ['?', ''], [2,3], [2,3], 'dialog'); -testJumplist('jumplist_skip_deleted_mark', - ['*', 'n', 'n', 'k', 'd', 'k', '', '', ''], - [0,2], [0,2]); -testJumplist('jumplist_skip_deleted_mark', - ['*', 'n', 'n', 'k', 'd', 'k', '', '', ''], - [1,0], [0,2]); - -/** - * @param name Name of the test - * @param keys An array of keys or a string with a single key to simulate. - * @param endPos The expected end position of the cursor. - * @param startPos The position the cursor should start at, defaults to 0, 0. - */ -function testMotion(name, keys, endPos, startPos) { - testVim(name, function(cm, vim, helpers) { - if (!startPos) { - startPos = new Pos(0, 0); - } - cm.setCursor(startPos); - helpers.doKeys(keys); - helpers.assertCursorAt(endPos); - }); -} - -function makeCursor(line, ch) { - return new Pos(line, ch); -} - -function offsetCursor(cur, offsetLine, offsetCh) { - return new Pos(cur.line + offsetLine, cur.ch + offsetCh); -} - -// Motion tests -testMotion('|', '|', makeCursor(0, 0), makeCursor(0,4)); -testMotion('|_repeat', ['3', '|'], makeCursor(0, 2), makeCursor(0,4)); -testMotion('h', 'h', makeCursor(0, 0), word1.start); -testMotion('h_repeat', ['3', 'h'], offsetCursor(word1.end, 0, -3), word1.end); -testMotion('l', 'l', makeCursor(0, 1)); -testMotion('l_repeat', ['2', 'l'], makeCursor(0, 2)); -testMotion('j', 'j', offsetCursor(word1.end, 1, 0), word1.end); -testMotion('j_repeat', ['2', 'j'], offsetCursor(word1.end, 2, 0), word1.end); -testMotion('j_repeat_clip', ['1000', 'j'], endOfDocument); -testMotion('k', 'k', offsetCursor(word3.end, -1, 0), word3.end); -testMotion('k_repeat', ['2', 'k'], makeCursor(0, 4), makeCursor(2, 4)); -testMotion('k_repeat_clip', ['1000', 'k'], makeCursor(0, 4), makeCursor(2, 4)); -testMotion('w', 'w', word1.start); -testMotion('w_multiple_newlines_no_space', 'w', makeCursor(12, 2), makeCursor(11, 2)); -testMotion('w_multiple_newlines_with_space', 'w', makeCursor(14, 0), makeCursor(12, 51)); -testMotion('w_repeat', ['2', 'w'], word2.start); -testMotion('w_wrap', ['w'], word3.start, word2.start); -testMotion('w_endOfDocument', 'w', endOfDocument, endOfDocument); -testMotion('w_start_to_end', ['1000', 'w'], endOfDocument, makeCursor(0, 0)); -testMotion('W', 'W', bigWord1.start); -testMotion('W_repeat', ['2', 'W'], bigWord3.start, bigWord1.start); -testMotion('e', 'e', word1.end); -testMotion('e_repeat', ['2', 'e'], word2.end); -testMotion('e_wrap', 'e', word3.end, word2.end); -testMotion('e_endOfDocument', 'e', endOfDocument, endOfDocument); -testMotion('e_start_to_end', ['1000', 'e'], endOfDocument, makeCursor(0, 0)); -testMotion('b', 'b', word3.start, word3.end); -testMotion('b_repeat', ['2', 'b'], word2.start, word3.end); -testMotion('b_wrap', 'b', word2.start, word3.start); -testMotion('b_startOfDocument', 'b', makeCursor(0, 0), makeCursor(0, 0)); -testMotion('b_end_to_start', ['1000', 'b'], makeCursor(0, 0), endOfDocument); -testMotion('ge', ['g', 'e'], word2.end, word3.end); -testMotion('ge_repeat', ['2', 'g', 'e'], word1.end, word3.start); -testMotion('ge_wrap', ['g', 'e'], word2.end, word3.start); -testMotion('ge_startOfDocument', ['g', 'e'], makeCursor(0, 0), - makeCursor(0, 0)); -testMotion('ge_end_to_start', ['1000', 'g', 'e'], makeCursor(0, 0), endOfDocument); -testMotion('gg', ['g', 'g'], makeCursor(lines[0].line, lines[0].textStart), - makeCursor(3, 1)); -testMotion('gg_repeat', ['3', 'g', 'g'], - makeCursor(lines[2].line, lines[2].textStart)); -testMotion('G', 'G', - makeCursor(lines[lines.length - 1].line, lines[lines.length - 1].textStart), - makeCursor(3, 1)); -testMotion('G_repeat', ['3', 'G'], makeCursor(lines[2].line, - lines[2].textStart)); -// TODO: Make the test code long enough to test Ctrl-F and Ctrl-B. -testMotion('0', '0', makeCursor(0, 0), makeCursor(0, 8)); -testMotion('^', '^', makeCursor(0, lines[0].textStart), makeCursor(0, 8)); -testMotion('+', '+', makeCursor(1, lines[1].textStart), makeCursor(0, 8)); -testMotion('-', '-', makeCursor(0, lines[0].textStart), makeCursor(1, 4)); -testMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8)); -testMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1)); -testMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1), - makeCursor(0, 3)); -testMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0)); -testMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]); -testMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0)); -testMotion('t', ['t','p'], offsetCursor(pChars[0], 0, -1), - makeCursor(charLine.line, 0)); -testMotion('t_repeat', ['2', 't', 'p'], offsetCursor(pChars[2], 0, -1), - pChars[0]); -testMotion('F', ['F', 'p'], pChars[0], pChars[1]); -testMotion('F_repeat', ['2', 'F', 'p'], pChars[0], pChars[2]); -testMotion('T', ['T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[1]); -testMotion('T_repeat', ['2', 'T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[2]); -testMotion('%_parens', ['%'], parens1.end, parens1.start); -testMotion('%_squares', ['%'], squares1.end, squares1.start); -testMotion('%_braces', ['%'], curlys1.end, curlys1.start); -testMotion('%_seek_outside', ['%'], seekOutside.end, seekOutside.start); -testMotion('%_seek_inside', ['%'], seekInside.end, seekInside.start); -testVim('%_seek_skip', function(cm, vim, helpers) { - cm.setCursor(0,0); - helpers.doKeys(['%']); - helpers.assertCursorAt(0,9); -}, {value:'01234"("()'}); -testVim('%_skip_string', function(cm, vim, helpers) { - cm.setCursor(0,0); - helpers.doKeys(['%']); - helpers.assertCursorAt(0,4); - cm.setCursor(0,2); - helpers.doKeys(['%']); - helpers.assertCursorAt(0,0); -}, {value:'(")")'}); -testVim('%_skip_comment', function(cm, vim, helpers) { - cm.setCursor(0,0); - helpers.doKeys(['%']); - helpers.assertCursorAt(0,6); - cm.setCursor(0,3); - helpers.doKeys(['%']); - helpers.assertCursorAt(0,0); -}, {value:'(/*)*/)'}); -// Make sure that moving down after going to the end of a line always leaves you -// at the end of a line, but preserves the offset in other cases -testVim('Changing lines after Eol operation', function(cm, vim, helpers) { - cm.setCursor(0,0); - helpers.doKeys(['$']); - helpers.doKeys(['j']); - // After moving to Eol and then down, we should be at Eol of line 2 - helpers.assertCursorAt(new Pos(1, lines[1].length - 1)); - helpers.doKeys(['j']); - // After moving down, we should be at Eol of line 3 - helpers.assertCursorAt(new Pos(2, lines[2].length - 1)); - helpers.doKeys(['h']); - helpers.doKeys(['j']); - // After moving back one space and then down, since line 4 is shorter than line 2, we should - // be at Eol of line 2 - 1 - helpers.assertCursorAt(new Pos(3, lines[3].length - 1)); - helpers.doKeys(['j']); - helpers.doKeys(['j']); - // After moving down again, since line 3 has enough characters, we should be back to the - // same place we were at on line 1 - helpers.assertCursorAt(new Pos(5, lines[2].length - 2)); -}); -//making sure gj and gk recover from clipping -testVim('gj_gk_clipping', function(cm,vim,helpers){ - cm.setCursor(0, 1); - helpers.doKeys('g','j','g','j'); - helpers.assertCursorAt(2, 1); - helpers.doKeys('g','k','g','k'); - helpers.assertCursorAt(0, 1); -},{value: 'line 1\n\nline 2'}); -//testing a mix of j/k and gj/gk -testVim('j_k_and_gj_gk', function(cm,vim,helpers){ - if (phantom) return; - cm.setSize(120); - cm.setCursor(0, 0); - //go to the last character on the first line - helpers.doKeys('$'); - //move up/down on the column within the wrapped line - //side-effect: cursor is not locked to eol anymore - helpers.doKeys('g','k'); - var cur=cm.getCursor(); - eq(cur.line,0); - is((cur.ch<176),'gk didn\'t move cursor back (1)'); - helpers.doKeys('g','j'); - helpers.assertCursorAt(0, 176); - //should move to character 177 on line 2 (j/k preserve character index within line) - helpers.doKeys('j'); - //due to different line wrapping, the cursor can be on a different screen-x now - //gj and gk preserve screen-x on movement, much like moveV - helpers.doKeys('3','g','k'); - cur=cm.getCursor(); - eq(cur.line,1); - is((cur.ch<176),'gk didn\'t move cursor back (2)'); - helpers.doKeys('g','j','2','g','j'); - //should return to the same character-index - helpers.doKeys('k'); - helpers.assertCursorAt(0, 176); -},{ lineWrapping:true, value: 'This line is intentially long to test movement of gj and gk over wrapped lines. I will start on the end of this line, then make 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.'}); -testVim('gj_gk', function(cm, vim, helpers) { - if (phantom) return; - cm.setSize(120); - // Test top of document edge case. - cm.setCursor(0, 4); - helpers.doKeys('g', 'j'); - helpers.doKeys('10', 'g', 'k'); - helpers.assertCursorAt(0, 4); - - // Test moving down preserves column position. - helpers.doKeys('g', 'j'); - var pos1 = cm.getCursor(); - var expectedPos2 = new Pos(0, (pos1.ch - 4) * 2 + 4); - helpers.doKeys('g', 'j'); - helpers.assertCursorAt(expectedPos2); - - // Move to the last character - cm.setCursor(0, 0); - // Move left to reset HSPos - helpers.doKeys('h'); - // Test bottom of document edge case. - helpers.doKeys('100', 'g', 'j'); - var endingPos = cm.getCursor(); - is(endingPos != 0, 'gj should not be on wrapped line 0'); - var topLeftCharCoords = cm.charCoords(makeCursor(0, 0)); - var endingCharCoords = cm.charCoords(endingPos); - is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0'); -},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentionallylongtotestmovementofgjandgkoverwrappedlines.' }); -testVim('}', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('}'); - helpers.assertCursorAt(1, 0); - cm.setCursor(0, 0); - helpers.doKeys('2', '}'); - helpers.assertCursorAt(4, 0); - cm.setCursor(0, 0); - helpers.doKeys('6', '}'); - helpers.assertCursorAt(5, 0); -}, { value: 'a\n\nb\nc\n\nd' }); -testVim('{', function(cm, vim, helpers) { - cm.setCursor(5, 0); - helpers.doKeys('{'); - helpers.assertCursorAt(4, 0); - cm.setCursor(5, 0); - helpers.doKeys('2', '{'); - helpers.assertCursorAt(1, 0); - cm.setCursor(5, 0); - helpers.doKeys('6', '{'); - helpers.assertCursorAt(0, 0); -}, { value: 'a\n\nb\nc\n\nd' }); -testVim('paragraph_motions', function(cm, vim, helpers) { - cm.setCursor(10, 0); - helpers.doKeys('{'); - helpers.assertCursorAt(4, 0); - helpers.doKeys('{'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('2', '}'); - helpers.assertCursorAt(7, 0); - helpers.doKeys('2', '}'); - helpers.assertCursorAt(16, 0); - - cm.setCursor(9, 0); - helpers.doKeys('}'); - helpers.assertCursorAt(14, 0); - - cm.setCursor(6, 0); - helpers.doKeys('}'); - helpers.assertCursorAt(7, 0); - - // ip inside empty space - cm.setCursor(10, 0); - helpers.doKeys('v', 'i', 'p'); - eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); - eqCursorPos(Pos(12, 0), cm.getCursor('head')); - helpers.doKeys('i', 'p'); - eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); - eqCursorPos(Pos(13, 1), cm.getCursor('head')); - helpers.doKeys('2', 'i', 'p'); - eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); - eqCursorPos(Pos(16, 1), cm.getCursor('head')); - - // should switch to visualLine mode - cm.setCursor(14, 0); - helpers.doKeys('', 'v', 'i', 'p'); - helpers.assertCursorAt(14, 0); - - cm.setCursor(14, 0); - helpers.doKeys('', 'V', 'i', 'p'); - eqCursorPos(Pos(16, 1), cm.getCursor('head')); - - // ap inside empty space - cm.setCursor(10, 0); - helpers.doKeys('', 'v', 'a', 'p'); - eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); - eqCursorPos(Pos(13, 1), cm.getCursor('head')); - helpers.doKeys('a', 'p'); - eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); - eqCursorPos(Pos(16, 1), cm.getCursor('head')); - - cm.setCursor(13, 0); - helpers.doKeys('v', 'a', 'p'); - eqCursorPos(Pos(13, 0), cm.getCursor('anchor')); - eqCursorPos(Pos(14, 0), cm.getCursor('head')); - - cm.setCursor(16, 0); - helpers.doKeys('v', 'a', 'p'); - eqCursorPos(Pos(14, 0), cm.getCursor('anchor')); - eqCursorPos(Pos(16, 1), cm.getCursor('head')); - - cm.setCursor(0, 0); - helpers.doKeys('v', 'a', 'p'); - eqCursorPos(Pos(0, 0), cm.getCursor('anchor')); - eqCursorPos(Pos(4, 0), cm.getCursor('head')); - - cm.setCursor(0, 0); - helpers.doKeys('d', 'i', 'p'); - var register = helpers.getRegisterController().getRegister(); - eq('a\na\n', register.toString()); - is(register.linewise); - helpers.doKeys('3', 'j', 'p'); - helpers.doKeys('y', 'i', 'p'); - is(register.linewise); - eq('b\na\na\nc\n', register.toString()); -}, { value: 'a\na\n\n\n\nb\nc\n\n\n\n\n\n\nd\n\ne\nf' }); - -// Operator tests -testVim('dl', function(cm, vim, helpers) { - var curStart = makeCursor(0, 0); - cm.setCursor(curStart); - helpers.doKeys('d', 'l'); - eq('word1 ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' ', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}, { value: ' word1 ' }); -testVim('dl_eol', function(cm, vim, helpers) { - cm.setCursor(0, 6); - helpers.doKeys('d', 'l'); - eq(' word1', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' ', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 5); -}, { value: ' word1 ' }); -testVim('dl_repeat', function(cm, vim, helpers) { - var curStart = makeCursor(0, 0); - cm.setCursor(curStart); - helpers.doKeys('2', 'd', 'l'); - eq('ord1 ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' w', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}, { value: ' word1 ' }); -testVim('dh', function(cm, vim, helpers) { - var curStart = makeCursor(0, 3); - cm.setCursor(curStart); - helpers.doKeys('d', 'h'); - eq(' wrd1 ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('o', register.toString()); - is(!register.linewise); - eqCursorPos(offsetCursor(curStart, 0 , -1), cm.getCursor()); -}, { value: ' word1 ' }); -testVim('dj', function(cm, vim, helpers) { - var curStart = makeCursor(0, 3); - cm.setCursor(curStart); - helpers.doKeys('d', 'j'); - eq(' word3', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' word1\nword2\n', register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, 1); -}, { value: ' word1\nword2\n word3' }); -testVim('dj_end_of_document', function(cm, vim, helpers) { - var curStart = makeCursor(0, 3); - cm.setCursor(curStart); - helpers.doKeys('d', 'j'); - eq('', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' word1 \n', register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, 0); -}, { value: ' word1 ' }); -testVim('dk', function(cm, vim, helpers) { - var curStart = makeCursor(1, 3); - cm.setCursor(curStart); - helpers.doKeys('d', 'k'); - eq(' word3', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' word1\nword2\n', register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, 1); -}, { value: ' word1\nword2\n word3' }); -testVim('dk_start_of_document', function(cm, vim, helpers) { - var curStart = makeCursor(0, 3); - cm.setCursor(curStart); - helpers.doKeys('d', 'k'); - eq('', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' word1 \n', register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, 0); -}, { value: ' word1 ' }); -testVim('dw_space', function(cm, vim, helpers) { - var curStart = makeCursor(0, 0); - cm.setCursor(curStart); - helpers.doKeys('d', 'w'); - eq('word1 ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' ', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}, { value: ' word1 ' }); -testVim('dw_word', function(cm, vim, helpers) { - var curStart = makeCursor(0, 1); - cm.setCursor(curStart); - helpers.doKeys('d', 'w'); - eq(' word2', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1 ', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}, { value: ' word1 word2' }); -testVim('dw_unicode_word', function(cm, vim, helpers) { - helpers.doKeys('d', 'w'); - eq(cm.getValue().length, 10); - helpers.doKeys('d', 'w'); - eq(cm.getValue().length, 6); - helpers.doKeys('d', 'w'); - eq(cm.getValue().length, 5); - helpers.doKeys('d', 'e'); - eq(cm.getValue().length, 2); -}, { value: ' \u0562\u0561\u0580\u0587\xbbe\xb5g ' }); -testVim('dw_only_word', function(cm, vim, helpers) { - // Test that if there is only 1 word left, dw deletes till the end of the - // line. - cm.setCursor(0, 1); - helpers.doKeys('d', 'w'); - eq(' ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1 ', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 0); -}, { value: ' word1 ' }); -testVim('dw_eol', function(cm, vim, helpers) { - // Assert that dw does not delete the newline if last word to delete is at end - // of line. - cm.setCursor(0, 1); - helpers.doKeys('d', 'w'); - eq(' \nword2', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 0); -}, { value: ' word1\nword2' }); -testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) { - // Assert that dw does not delete the newline if last word to delete is at end - // of line and it is followed by multiple newlines. - cm.setCursor(0, 1); - helpers.doKeys('d', 'w'); - eq(' \n\nword2', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 0); -}, { value: ' word1\n\nword2' }); -testVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'w'); - eq(' \nword', cm.getValue()); -}, { value: '\n \nword' }); -testVim('dw_empty_line_followed_by_word', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'w'); - eq('word', cm.getValue()); -}, { value: '\nword' }); -testVim('dw_empty_line_followed_by_empty_line', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'w'); - eq('\n', cm.getValue()); -}, { value: '\n\n' }); -testVim('dw_whitespace_followed_by_whitespace', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'w'); - eq('\n \n', cm.getValue()); -}, { value: ' \n \n' }); -testVim('dw_whitespace_followed_by_empty_line', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'w'); - eq('\n\n', cm.getValue()); -}, { value: ' \n\n' }); -testVim('dw_word_whitespace_word', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'w'); - eq('\n \nword2', cm.getValue()); -}, { value: 'word1\n \nword2'}) -testVim('dw_end_of_document', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('d', 'w'); - eq('\nab', cm.getValue()); -}, { value: '\nabc' }); -testVim('dw_repeat', function(cm, vim, helpers) { - // Assert that dw does delete newline if it should go to the next line, and - // that repeat works properly. - cm.setCursor(0, 1); - helpers.doKeys('d', '2', 'w'); - eq(' ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1\nword2', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 0); -}, { value: ' word1\nword2' }); -testVim('de_word_start_and_empty_lines', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'e'); - eq('\n\n', cm.getValue()); -}, { value: 'word\n\n' }); -testVim('de_word_end_and_empty_lines', function(cm, vim, helpers) { - cm.setCursor(0, 3); - helpers.doKeys('d', 'e'); - eq('wor', cm.getValue()); -}, { value: 'word\n\n\n' }); -testVim('de_whitespace_and_empty_lines', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'e'); - eq('', cm.getValue()); -}, { value: ' \n\n\n' }); -testVim('de_end_of_document', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('d', 'e'); - eq('\nab', cm.getValue()); -}, { value: '\nabc' }); -testVim('db_empty_lines', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('d', 'b'); - eq('\n\n', cm.getValue()); -}, { value: '\n\n\n' }); -testVim('db_word_start_and_empty_lines', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('d', 'b'); - eq('\nword', cm.getValue()); -}, { value: '\n\nword' }); -testVim('db_word_end_and_empty_lines', function(cm, vim, helpers) { - cm.setCursor(2, 3); - helpers.doKeys('d', 'b'); - eq('\n\nd', cm.getValue()); -}, { value: '\n\nword' }); -testVim('db_whitespace_and_empty_lines', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('d', 'b'); - eq('', cm.getValue()); -}, { value: '\n \n' }); -testVim('db_start_of_document', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'b'); - eq('abc\n', cm.getValue()); -}, { value: 'abc\n' }); -testVim('dge_empty_lines', function(cm, vim, helpers) { - cm.setCursor(1, 0); - helpers.doKeys('d', 'g', 'e'); - // Note: In real VIM the result should be '', but it's not quite consistent, - // since 2 newlines are deleted. But in the similar case of word\n\n, only - // 1 newline is deleted. We'll diverge from VIM's behavior since it's much - // easier this way. - eq('\n', cm.getValue()); -}, { value: '\n\n' }); -testVim('dge_word_and_empty_lines', function(cm, vim, helpers) { - cm.setCursor(1, 0); - helpers.doKeys('d', 'g', 'e'); - eq('wor\n', cm.getValue()); -}, { value: 'word\n\n'}); -testVim('dge_whitespace_and_empty_lines', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('d', 'g', 'e'); - eq('', cm.getValue()); -}, { value: '\n \n' }); -testVim('dge_start_of_document', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('d', 'g', 'e'); - eq('bc\n', cm.getValue()); -}, { value: 'abc\n' }); -testVim('d_inclusive', function(cm, vim, helpers) { - // Assert that when inclusive is set, the character the cursor is on gets - // deleted too. - var curStart = makeCursor(0, 1); - cm.setCursor(curStart); - helpers.doKeys('d', 'e'); - eq(' ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}, { value: ' word1 ' }); -testVim('d_reverse', function(cm, vim, helpers) { - // Test that deleting in reverse works. - cm.setCursor(1, 0); - helpers.doKeys('d', 'b'); - eq(' word2 ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1\n', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 1); -}, { value: ' word1\nword2 ' }); -testVim('dd', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedBuffer = cm.getRange(new Pos(0, 0), - new Pos(1, 0)); - var expectedLineCount = cm.lineCount() - 1; - helpers.doKeys('d', 'd'); - eq(expectedLineCount, cm.lineCount()); - var register = helpers.getRegisterController().getRegister(); - eq(expectedBuffer, register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, lines[1].textStart); -}); -testVim('dd_prefix_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedBuffer = cm.getRange(new Pos(0, 0), - new Pos(2, 0)); - var expectedLineCount = cm.lineCount() - 2; - helpers.doKeys('2', 'd', 'd'); - eq(expectedLineCount, cm.lineCount()); - var register = helpers.getRegisterController().getRegister(); - eq(expectedBuffer, register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, lines[2].textStart); -}); -testVim('dd_motion_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedBuffer = cm.getRange(new Pos(0, 0), - new Pos(2, 0)); - var expectedLineCount = cm.lineCount() - 2; - helpers.doKeys('d', '2', 'd'); - eq(expectedLineCount, cm.lineCount()); - var register = helpers.getRegisterController().getRegister(); - eq(expectedBuffer, register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, lines[2].textStart); -}); -testVim('dd_multiply_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedBuffer = cm.getRange(new Pos(0, 0), - new Pos(6, 0)); - var expectedLineCount = cm.lineCount() - 6; - helpers.doKeys('2', 'd', '3', 'd'); - eq(expectedLineCount, cm.lineCount()); - var register = helpers.getRegisterController().getRegister(); - eq(expectedBuffer, register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, lines[6].textStart); -}); -testVim('dd_lastline', function(cm, vim, helpers) { - cm.setCursor(cm.lineCount(), 0); - var expectedLineCount = cm.lineCount() - 1; - helpers.doKeys('d', 'd'); - eq(expectedLineCount, cm.lineCount()); - helpers.assertCursorAt(cm.lineCount() - 1, 0); -}); -testVim('dd_only_line', function(cm, vim, helpers) { - cm.setCursor(0, 0); - var expectedRegister = cm.getValue() + "\n"; - helpers.doKeys('d','d'); - eq(1, cm.lineCount()); - eq('', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(expectedRegister, register.toString()); -}, { value: "thisistheonlyline" }); -// Yank commands should behave the exact same as d commands, expect that nothing -// gets deleted. -testVim('yw_repeat', function(cm, vim, helpers) { - // Assert that yw does yank newline if it should go to the next line, and - // that repeat works properly. - var curStart = makeCursor(0, 1); - cm.setCursor(curStart); - helpers.doKeys('y', '2', 'w'); - eq(' word1\nword2', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1\nword2', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}, { value: ' word1\nword2' }); -testVim('yy_multiply_repeat', function(cm, vim, helpers) { - var curStart = makeCursor(0, 3); - cm.setCursor(curStart); - var expectedBuffer = cm.getRange(new Pos(0, 0), - new Pos(6, 0)); - var expectedLineCount = cm.lineCount(); - helpers.doKeys('2', 'y', '3', 'y'); - eq(expectedLineCount, cm.lineCount()); - var register = helpers.getRegisterController().getRegister(); - eq(expectedBuffer, register.toString()); - is(register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}); -testVim('2dd_blank_P', function(cm, vim, helpers) { - helpers.doKeys('2', 'd', 'd', 'P'); - eq('\na\n\n', cm.getValue()); -}, { value: '\na\n\n' }); -// Change commands behave like d commands except that it also enters insert -// mode. In addition, when the change is linewise, an additional newline is -// inserted so that insert mode starts on that line. -testVim('cw', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('c', '2', 'w'); - eq(' word3', cm.getValue()); - helpers.assertCursorAt(0, 0); -}, { value: 'word1 word2 word3'}); -testVim('cw_repeat', function(cm, vim, helpers) { - // Assert that cw does delete newline if it should go to the next line, and - // that repeat works properly. - var curStart = makeCursor(0, 1); - cm.setCursor(curStart); - helpers.doKeys('c', '2', 'w'); - eq(' ', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word1\nword2', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); - eq('vim-insert', cm.getOption('keyMap')); -}, { value: ' word1\nword2' }); -testVim('cc_multiply_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedBuffer = cm.getRange(new Pos(0, 0), - new Pos(6, 0)); - var expectedLineCount = cm.lineCount() - 5; - helpers.doKeys('2', 'c', '3', 'c'); - eq(expectedLineCount, cm.lineCount()); - var register = helpers.getRegisterController().getRegister(); - eq(expectedBuffer, register.toString()); - is(register.linewise); - eq('vim-insert', cm.getOption('keyMap')); -}); -testVim('ct', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('c', 't', 'w'); - eq(' word1 word3', cm.getValue()); - helpers.doKeys('', 'c', '|'); - eq(' word3', cm.getValue()); - helpers.assertCursorAt(0, 0); - helpers.doKeys('', '2', 'u', 'w', 'h'); - helpers.doKeys('c', '2', 'g', 'e'); - eq(' wordword3', cm.getValue()); -}, { value: ' word1 word2 word3'}); -testVim('cc_should_not_append_to_document', function(cm, vim, helpers) { - var expectedLineCount = cm.lineCount(); - cm.setCursor(cm.lastLine(), 0); - helpers.doKeys('c', 'c'); - eq(expectedLineCount, cm.lineCount()); -}); -function fillArray(val, times) { - var arr = []; - for (var i = 0; i < times; i++) { - arr.push(val); - } - return arr; -} -testVim('c_visual_block', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('', '2', 'j', 'l', 'l', 'l', 'c'); - var replacement = fillArray('hello', 3); - cm.replaceSelections(replacement); - eq('1hello\n5hello\nahellofg', cm.getValue()); - helpers.doKeys(''); - cm.setCursor(2, 3); - helpers.doKeys('', '2', 'k', 'h', 'C'); - replacement = fillArray('world', 3); - cm.replaceSelections(replacement); - eq('1hworld\n5hworld\nahworld', cm.getValue()); -}, {value: '1234\n5678\nabcdefg'}); -testVim('c_visual_block_replay', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('', '2', 'j', 'l', 'c'); - var replacement = fillArray('fo', 3); - cm.replaceSelections(replacement); - eq('1fo4\n5fo8\nafodefg', cm.getValue()); - helpers.doKeys(''); - cm.setCursor(0, 0); - helpers.doKeys('.'); - eq('foo4\nfoo8\nfoodefg', cm.getValue()); -}, {value: '1234\n5678\nabcdefg'}); - -testVim('d_visual_block', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('', '2', 'j', 'l', 'l', 'l', 'd'); - eq('1\n5\nafg', cm.getValue()); -}, {value: '1234\n5678\nabcdefg'}); -testVim('D_visual_block', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('', '2', 'j', 'l', 'D'); - eq('1\n5\na', cm.getValue()); -}, {value: '1234\n5678\nabcdefg'}); - -testVim('s_visual_block', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('', '2', 'j', 'l', 'l', 'l', 's'); - var replacement = fillArray('hello{', 3); - cm.replaceSelections(replacement); - eq('1hello{\n5hello{\nahello{fg\n', cm.getValue()); - helpers.doKeys(''); - cm.setCursor(2, 3); - helpers.doKeys('', '1', 'k', 'h', 'S'); - replacement = fillArray('world', 1); - cm.replaceSelections(replacement); - eq('1hello{\n world\n', cm.getValue()); -}, {value: '1234\n5678\nabcdefg\n'}); - -// Swapcase commands edit in place and do not modify registers. -testVim('g~w_repeat', function(cm, vim, helpers) { - // Assert that dw does delete newline if it should go to the next line, and - // that repeat works properly. - var curStart = makeCursor(0, 1); - cm.setCursor(curStart); - helpers.doKeys('g', '~', '2', 'w'); - eq(' WORD1\nWORD2', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}, { value: ' word1\nword2' }); -testVim('g~g~', function(cm, vim, helpers) { - var curStart = makeCursor(0, 3); - cm.setCursor(curStart); - var expectedLineCount = cm.lineCount(); - var expectedValue = cm.getValue().toUpperCase(); - helpers.doKeys('2', 'g', '~', '3', 'g', '~'); - eq(expectedValue, cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); -}, { value: ' word1\nword2\nword3\nword4\nword5\nword6' }); -testVim('gu_and_gU', function(cm, vim, helpers) { - var curStart = makeCursor(0, 7); - var value = cm.getValue(); - cm.setCursor(curStart); - helpers.doKeys('2', 'g', 'U', 'w'); - eq(cm.getValue(), 'wa wb xX WC wd'); - eqCursorPos(curStart, cm.getCursor()); - helpers.doKeys('2', 'g', 'u', 'w'); - eq(cm.getValue(), value); - - helpers.doKeys('2', 'g', 'U', 'B'); - eq(cm.getValue(), 'wa WB Xx wc wd'); - eqCursorPos(makeCursor(0, 3), cm.getCursor()); - - cm.setCursor(makeCursor(0, 4)); - helpers.doKeys('g', 'u', 'i', 'w'); - eq(cm.getValue(), 'wa wb Xx wc wd'); - eqCursorPos(makeCursor(0, 3), cm.getCursor()); - - // TODO: support gUgU guu - // eqCursorPos(makeCursor(0, 0), cm.getCursor()); - - var register = helpers.getRegisterController().getRegister(); - eq('', register.toString()); - is(!register.linewise); -}, { value: 'wa wb xx wc wd' }); -testVim('visual_block_~', function(cm, vim, helpers) { - cm.setCursor(1, 1); - helpers.doKeys('', 'l', 'l', 'j', '~'); - helpers.assertCursorAt(1, 1); - eq('hello\nwoRLd\naBCDe', cm.getValue()); - cm.setCursor(2, 0); - helpers.doKeys('v', 'l', 'l', '~'); - helpers.assertCursorAt(2, 0); - eq('hello\nwoRLd\nAbcDe', cm.getValue()); -},{value: 'hello\nwOrld\nabcde' }); -testVim('._swapCase_visualBlock', function(cm, vim, helpers) { - helpers.doKeys('', 'j', 'j', 'l', '~'); - cm.setCursor(0, 3); - helpers.doKeys('.'); - eq('HelLO\nWorLd\nAbcdE', cm.getValue()); -},{value: 'hEllo\nwOrlD\naBcDe' }); -testVim('._delete_visualBlock', function(cm, vim, helpers) { - helpers.doKeys('', 'j', 'x'); - eq('ive\ne\nsome\nsugar', cm.getValue()); - helpers.doKeys('.'); - eq('ve\n\nsome\nsugar', cm.getValue()); - helpers.doKeys('j', 'j', '.'); - eq('ve\n\nome\nugar', cm.getValue()); - helpers.doKeys('u', '', '.'); - eq('ve\n\nme\ngar', cm.getValue()); -},{value: 'give\nme\nsome\nsugar' }); -testVim('>{motion}', function(cm, vim, helpers) { - cm.setCursor(1, 3); - var expectedLineCount = cm.lineCount(); - var expectedValue = ' word1\n word2\nword3 '; - helpers.doKeys('>', 'k'); - eq(expectedValue, cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 3); -}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); -testVim('>>', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedLineCount = cm.lineCount(); - var expectedValue = ' word1\n word2\nword3 '; - helpers.doKeys('2', '>', '>'); - eq(expectedValue, cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 3); -}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); -testVim('<{motion}', function(cm, vim, helpers) { - cm.setCursor(1, 3); - var expectedLineCount = cm.lineCount(); - var expectedValue = ' word1\nword2\nword3 '; - helpers.doKeys('<', 'k'); - eq(expectedValue, cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 1); -}, { value: ' word1\n word2\nword3 ', indentUnit: 2 }); -testVim('<<', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedLineCount = cm.lineCount(); - var expectedValue = ' word1\nword2\nword3 '; - helpers.doKeys('2', '<', '<'); - eq(expectedValue, cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 1); -}, { value: ' word1\n word2\nword3 ', indentUnit: 2 }); - -// Edit tests -function testEdit(name, before, pos, edit, after) { - return testVim(name, function(cm, vim, helpers) { - var ch = before.search(pos) - var line = before.substring(0, ch).split('\n').length - 1; - if (line) { - ch = before.substring(0, ch).split('\n').pop().length; - } - cm.setCursor(line, ch); - helpers.doKeys.apply(this, edit.split('')); - eq(after, cm.getValue()); - }, {value: before}); -} - -// These Delete tests effectively cover word-wise Change, Visual & Yank. -// Tabs are used as differentiated whitespace to catch edge cases. -// Normal word: -testEdit('diw_mid_spc', 'foo \tbAr\t baz', /A/, 'diw', 'foo \t\t baz'); -testEdit('daw_mid_spc', 'foo \tbAr\t baz', /A/, 'daw', 'foo \tbaz'); -testEdit('diw_mid_punct', 'foo \tbAr.\t baz', /A/, 'diw', 'foo \t.\t baz'); -testEdit('daw_mid_punct', 'foo \tbAr.\t baz', /A/, 'daw', 'foo.\t baz'); -testEdit('diw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diw', 'foo \t,.\t baz'); -testEdit('daw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daw', 'foo \t,.\t baz'); -testEdit('diw_start_spc', 'bAr \tbaz', /A/, 'diw', ' \tbaz'); -testEdit('daw_start_spc', 'bAr \tbaz', /A/, 'daw', 'baz'); -testEdit('diw_start_punct', 'bAr. \tbaz', /A/, 'diw', '. \tbaz'); -testEdit('daw_start_punct', 'bAr. \tbaz', /A/, 'daw', '. \tbaz'); -testEdit('diw_end_spc', 'foo \tbAr', /A/, 'diw', 'foo \t'); -testEdit('daw_end_spc', 'foo \tbAr', /A/, 'daw', 'foo'); -testEdit('diw_end_punct', 'foo \tbAr.', /A/, 'diw', 'foo \t.'); -testEdit('daw_end_punct', 'foo \tbAr.', /A/, 'daw', 'foo.'); -// Big word: -testEdit('diW_mid_spc', 'foo \tbAr\t baz', /A/, 'diW', 'foo \t\t baz'); -testEdit('daW_mid_spc', 'foo \tbAr\t baz', /A/, 'daW', 'foo \tbaz'); -testEdit('diW_mid_punct', 'foo \tbAr.\t baz', /A/, 'diW', 'foo \t\t baz'); -testEdit('daW_mid_punct', 'foo \tbAr.\t baz', /A/, 'daW', 'foo \tbaz'); -testEdit('diW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diW', 'foo \t\t baz'); -testEdit('daW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daW', 'foo \tbaz'); -testEdit('diW_start_spc', 'bAr\t baz', /A/, 'diW', '\t baz'); -testEdit('daW_start_spc', 'bAr\t baz', /A/, 'daW', 'baz'); -testEdit('diW_start_punct', 'bAr.\t baz', /A/, 'diW', '\t baz'); -testEdit('daW_start_punct', 'bAr.\t baz', /A/, 'daW', 'baz'); -testEdit('diW_end_spc', 'foo \tbAr', /A/, 'diW', 'foo \t'); -testEdit('daW_end_spc', 'foo \tbAr', /A/, 'daW', 'foo'); -testEdit('diW_end_punct', 'foo \tbAr.', /A/, 'diW', 'foo \t'); -testEdit('daW_end_punct', 'foo \tbAr.', /A/, 'daW', 'foo'); -// Deleting text objects -// Open and close on same line -testEdit('di(_open_spc', 'foo (bAr) baz', /\(/, 'di(', 'foo () baz'); -testEdit('di)_open_spc', 'foo (bAr) baz', /\(/, 'di)', 'foo () baz'); -testEdit('dib_open_spc', 'foo (bAr) baz', /\(/, 'dib', 'foo () baz'); -testEdit('da(_open_spc', 'foo (bAr) baz', /\(/, 'da(', 'foo baz'); -testEdit('da)_open_spc', 'foo (bAr) baz', /\(/, 'da)', 'foo baz'); - -testEdit('di(_middle_spc', 'foo (bAr) baz', /A/, 'di(', 'foo () baz'); -testEdit('di)_middle_spc', 'foo (bAr) baz', /A/, 'di)', 'foo () baz'); -testEdit('da(_middle_spc', 'foo (bAr) baz', /A/, 'da(', 'foo baz'); -testEdit('da)_middle_spc', 'foo (bAr) baz', /A/, 'da)', 'foo baz'); - -testEdit('di(_close_spc', 'foo (bAr) baz', /\)/, 'di(', 'foo () baz'); -testEdit('di)_close_spc', 'foo (bAr) baz', /\)/, 'di)', 'foo () baz'); -testEdit('da(_close_spc', 'foo (bAr) baz', /\)/, 'da(', 'foo baz'); -testEdit('da)_close_spc', 'foo (bAr) baz', /\)/, 'da)', 'foo baz'); - -// delete around and inner b. -testEdit('dab_on_(_should_delete_around_()block', 'o( in(abc) )', /\(a/, 'dab', 'o( in )'); - -// delete around and inner B. -testEdit('daB_on_{_should_delete_around_{}block', 'o{ in{abc} }', /{a/, 'daB', 'o{ in }'); -testEdit('diB_on_{_should_delete_inner_{}block', 'o{ in{abc} }', /{a/, 'diB', 'o{ in{} }'); - -testEdit('da{_on_{_should_delete_inner_block', 'o{ in{abc} }', /{a/, 'da{', 'o{ in }'); -testEdit('di[_on_(_should_not_delete', 'foo (bAr) baz', /\(/, 'di[', 'foo (bAr) baz'); -testEdit('di[_on_)_should_not_delete', 'foo (bAr) baz', /\)/, 'di[', 'foo (bAr) baz'); -testEdit('da[_on_(_should_not_delete', 'foo (bAr) baz', /\(/, 'da[', 'foo (bAr) baz'); -testEdit('da[_on_)_should_not_delete', 'foo (bAr) baz', /\)/, 'da[', 'foo (bAr) baz'); -testMotion('di(_outside_should_stay', ['d', 'i', '('], new Pos(0, 0), new Pos(0, 0)); - -// Open and close on different lines, equally indented -testEdit('di{_middle_spc', 'a{\n\tbar\n}b', /r/, 'di{', 'a{}b'); -testEdit('di}_middle_spc', 'a{\n\tbar\n}b', /r/, 'di}', 'a{}b'); -testEdit('da{_middle_spc', 'a{\n\tbar\n}b', /r/, 'da{', 'ab'); -testEdit('da}_middle_spc', 'a{\n\tbar\n}b', /r/, 'da}', 'ab'); -testEdit('daB_middle_spc', 'a{\n\tbar\n}b', /r/, 'daB', 'ab'); - -// open and close on diff lines, open indented less than close -testEdit('di{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di{', 'a{}b'); -testEdit('di}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di}', 'a{}b'); -testEdit('da{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da{', 'ab'); -testEdit('da}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da}', 'ab'); - -// open and close on diff lines, open indented more than close -testEdit('di[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di[', 'a\t[]b'); -testEdit('di]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di]', 'a\t[]b'); -testEdit('da[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da[', 'a\tb'); -testEdit('da]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da]', 'a\tb'); - -function testSelection(name, before, pos, keys, sel) { - return testVim(name, function(cm, vim, helpers) { - var ch = before.search(pos) - var line = before.substring(0, ch).split('\n').length - 1; - if (line) { - ch = before.substring(0, ch).split('\n').pop().length; - } - cm.setCursor(line, ch); - helpers.doKeys.apply(this, keys.split('')); - eq(sel, cm.getSelection()); - }, {value: before}); -} -testSelection('viw_middle_spc', 'foo \tbAr\t baz', /A/, 'viw', 'bAr'); -testSelection('vaw_middle_spc', 'foo \tbAr\t baz', /A/, 'vaw', 'bAr\t '); -testSelection('viw_middle_punct', 'foo \tbAr,\t baz', /A/, 'viw', 'bAr'); -testSelection('vaW_middle_punct', 'foo \tbAr,\t baz', /A/, 'vaW', 'bAr,\t '); -testSelection('viw_start_spc', 'foo \tbAr\t baz', /b/, 'viw', 'bAr'); -testSelection('viw_end_spc', 'foo \tbAr\t baz', /r/, 'viw', 'bAr'); -testSelection('viw_eol', 'foo \tbAr', /r/, 'viw', 'bAr'); -testSelection('vi{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'vi{', '\n\tbar\n\t'); -testSelection('va{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'va{', '{\n\tbar\n\t}'); - -testVim('mouse_select', function(cm, vim, helpers) { - cm.setSelection(Pos(0, 2), Pos(0, 4), {origin: '*mouse'}); - is(cm.state.vim.visualMode); - is(!cm.state.vim.visualLine); - is(!cm.state.vim.visualBlock); - helpers.doKeys(''); - is(!cm.somethingSelected()); - helpers.doKeys('g', 'v'); - eq('cd', cm.getSelection()); -}, {value: 'abcdef'}); - -// Operator-motion tests -testVim('D', function(cm, vim, helpers) { - cm.setCursor(0, 3); - helpers.doKeys('D'); - eq(' wo\nword2\n word3', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('rd1', register.toString()); - is(!register.linewise); - helpers.assertCursorAt(0, 2); -}, { value: ' word1\nword2\n word3' }); -testVim('C', function(cm, vim, helpers) { - var curStart = makeCursor(0, 3); - cm.setCursor(curStart); - helpers.doKeys('C'); - eq(' wo\nword2\n word3', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('rd1', register.toString()); - is(!register.linewise); - eqCursorPos(curStart, cm.getCursor()); - eq('vim-insert', cm.getOption('keyMap')); -}, { value: ' word1\nword2\n word3' }); -testVim('Y', function(cm, vim, helpers) { - var curStart = makeCursor(0, 3); - cm.setCursor(curStart); - helpers.doKeys('Y'); - eq(' word1\nword2\n word3', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq(' word1\n', register.toString()); - is(register.linewise); - helpers.assertCursorAt(0, 3); -}, { value: ' word1\nword2\n word3' }); -testVim('~', function(cm, vim, helpers) { - helpers.doKeys('3', '~'); - eq('ABCdefg', cm.getValue()); - helpers.assertCursorAt(0, 3); -}, { value: 'abcdefg' }); - -// Action tests -testVim('ctrl-a', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys(''); - eq('-9', cm.getValue()); - helpers.assertCursorAt(0, 1); - helpers.doKeys('2',''); - eq('-7', cm.getValue()); -}, {value: '-10'}); -testVim('ctrl-x', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys(''); - eq('-1', cm.getValue()); - helpers.assertCursorAt(0, 1); - helpers.doKeys('2',''); - eq('-3', cm.getValue()); -}, {value: '0'}); -testVim('/ search forward', function(cm, vim, helpers) { - forEach(['', ''], function(key) { - cm.setCursor(0, 0); - helpers.doKeys(key); - helpers.assertCursorAt(0, 5); - helpers.doKeys('l'); - helpers.doKeys(key); - helpers.assertCursorAt(0, 10); - cm.setCursor(0, 11); - helpers.doKeys(key); - helpers.assertCursorAt(0, 11); - }); -}, {value: '__jmp1 jmp2 jmp'}); -testVim('insert_ctrl_w', function(cm, vim, helpers) { - var curStart = makeCursor(0, 10); - cm.setCursor(curStart); - helpers.doKeys('a'); - helpers.doKeys(''); - eq('word1/', cm.getValue()); - var register = helpers.getRegisterController().getRegister(); - eq('word2', register.toString()); - is(!register.linewise); - var curEnd = makeCursor(0, 6); - eqCursorPos(curEnd, cm.getCursor()); - eq('vim-insert', cm.getOption('keyMap')); -}, { value: 'word1/word2' }); -testVim('a', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('a'); - helpers.assertCursorAt(0, 2); - eq('vim-insert', cm.getOption('keyMap')); -}); -testVim('a_eol', function(cm, vim, helpers) { - cm.setCursor(0, lines[0].length - 1); - helpers.doKeys('a'); - helpers.assertCursorAt(0, lines[0].length); - eq('vim-insert', cm.getOption('keyMap')); -}); -testVim('A_endOfSelectedArea', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('v', 'j', 'l'); - helpers.doKeys('A'); - helpers.assertCursorAt(1, 2); - eq('vim-insert', cm.getOption('keyMap')); -}, {value: 'foo\nbar'}); -testVim('i', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('i'); - helpers.assertCursorAt(0, 1); - eq('vim-insert', cm.getOption('keyMap')); -}); -testVim('i_repeat', function(cm, vim, helpers) { - helpers.doKeys('3', 'i'); - cm.replaceRange('test', cm.getCursor()); - helpers.doKeys(''); - eq('testtesttest', cm.getValue()); - helpers.assertCursorAt(0, 11); -}, { value: '' }); -testVim('i_repeat_delete', function(cm, vim, helpers) { - cm.setCursor(0, 4); - helpers.doKeys('2', 'i'); - cm.replaceRange('z', cm.getCursor()); - helpers.doInsertModeKeys('Backspace', 'Backspace'); - helpers.doKeys(''); - eq('abe', cm.getValue()); - helpers.assertCursorAt(0, 1); -}, { value: 'abcde' }); -testVim('insert', function(cm, vim, helpers) { - helpers.doKeys('i'); - eq('vim-insert', cm.getOption('keyMap')); - eq(false, cm.state.overwrite); - helpers.doKeys(''); - eq('vim-replace', cm.getOption('keyMap')); - eq(true, cm.state.overwrite); - helpers.doKeys(''); - eq('vim-insert', cm.getOption('keyMap')); - eq(false, cm.state.overwrite); -}); -testVim('i_backspace', function(cm, vim, helpers) { - cm.setCursor(0, 10); - helpers.doKeys('i'); - helpers.doInsertModeKeys('Backspace'); - helpers.assertCursorAt(0, 9); - eq('012345678', cm.getValue()); -}, { value: '0123456789'}); -isAce || testVim('i_overwrite_backspace', function(cm, vim, helpers) { - cm.setCursor(0, 10); - helpers.doKeys('i'); - helpers.doKeys(''); - helpers.doInsertModeKeys('Backspace'); - helpers.assertCursorAt(Pos(0, 9, "after")); - eq('0123456789', cm.getValue()); -}, { value: '0123456789'}); -testVim('A', function(cm, vim, helpers) { - helpers.doKeys('A'); - helpers.assertCursorAt(0, lines[0].length); - eq('vim-insert', cm.getOption('keyMap')); -}); -testVim('A_visual_block', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('', '2', 'j', 'l', 'l', 'A'); - var replacement = new Array(cm.listSelections().length+1).join('hello ').split(' '); - replacement.pop(); - cm.replaceSelections(replacement); - eq('testhello\nmehello\npleahellose', cm.getValue()); - helpers.doKeys(''); - cm.setCursor(0, 0); - helpers.doKeys('.'); - // TODO this doesn't work yet - // eq('teshellothello\nme hello hello\nplehelloahellose', cm.getValue()); -}, {value: 'test\nme\nplease'}); -testVim('I', function(cm, vim, helpers) { - cm.setCursor(0, 4); - helpers.doKeys('I'); - helpers.assertCursorAt(0, lines[0].textStart); - eq('vim-insert', cm.getOption('keyMap')); -}); -testVim('I_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('3', 'I'); - cm.replaceRange('test', cm.getCursor()); - helpers.doKeys(''); - eq('testtesttestblah', cm.getValue()); - helpers.assertCursorAt(0, 11); -}, { value: 'blah' }); -testVim('I_visual_block', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('', '2', 'j', 'l', 'l', 'I'); - var replacement = new Array(cm.listSelections().length+1).join('hello ').split(' '); - replacement.pop(); - cm.replaceSelections(replacement); - eq('hellotest\nhellome\nhelloplease', cm.getValue()); -}, {value: 'test\nme\nplease'}); -testVim('o', function(cm, vim, helpers) { - cm.setCursor(0, 4); - helpers.doKeys('o'); - eq('word1\n\nword2', cm.getValue()); - helpers.assertCursorAt(1, 0); - eq('vim-insert', cm.getOption('keyMap')); -}, { value: 'word1\nword2' }); -testVim('o_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('3', 'o'); - cm.replaceRange('test', cm.getCursor()); - helpers.doKeys(''); - eq('\ntest\ntest\ntest', cm.getValue()); - helpers.assertCursorAt(3, 3); -}, { value: '' }); -testVim('O', function(cm, vim, helpers) { - cm.setCursor(0, 4); - helpers.doKeys('O'); - eq('\nword1\nword2', cm.getValue()); - helpers.assertCursorAt(0, 0); - eq('vim-insert', cm.getOption('keyMap')); -}, { value: 'word1\nword2' }); -testVim('J', function(cm, vim, helpers) { - cm.setCursor(0, 4); - helpers.doKeys('J'); - var expectedValue = 'word1 word2\nword3\n word4'; - eq(expectedValue, cm.getValue()); - helpers.assertCursorAt(0, expectedValue.indexOf('word2') - 1); -}, { value: 'word1 \n word2\nword3\n word4' }); -testVim('J_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 4); - helpers.doKeys('3', 'J'); - var expectedValue = 'word1 word2 word3\n word4'; - eq(expectedValue, cm.getValue()); - helpers.assertCursorAt(0, expectedValue.indexOf('word3') - 1); -}, { value: 'word1 \n word2\nword3\n word4' }); -testVim('p', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false); - helpers.doKeys('p'); - eq('__abc\ndef_', cm.getValue()); - helpers.assertCursorAt(1, 2); -}, { value: '___' }); -testVim('p_register', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.getRegisterController().getRegister('a').setText('abc\ndef', false); - helpers.doKeys('"', 'a', 'p'); - eq('__abc\ndef_', cm.getValue()); - helpers.assertCursorAt(1, 2); -}, { value: '___' }); -testVim('p_wrong_register', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.getRegisterController().getRegister('a').setText('abc\ndef', false); - helpers.doKeys('p'); - eq('___', cm.getValue()); - helpers.assertCursorAt(0, 1); -}, { value: '___' }); -testVim('p_line', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true); - helpers.doKeys('2', 'p'); - eq('___\n a\nd\n a\nd', cm.getValue()); - helpers.assertCursorAt(1, 2); -}, { value: '___' }); -testVim('p_lastline', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.getRegisterController().pushText('"', 'yank', ' a\nd', true); - helpers.doKeys('2', 'p'); - eq('___\n a\nd\n a\nd', cm.getValue()); - helpers.assertCursorAt(1, 2); -}, { value: '___' }); -testVim(']p_first_indent_is_smaller', function(cm, vim, helpers) { - helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); - helpers.doKeys(']', 'p'); - eq(' ___\n abc\n def', cm.getValue()); -}, { value: ' ___' }); -testVim(']p_first_indent_is_larger', function(cm, vim, helpers) { - helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); - helpers.doKeys(']', 'p'); - eq(' ___\n abc\ndef', cm.getValue()); -}, { value: ' ___' }); -testVim(']p_with_tab_indents', function(cm, vim, helpers) { - helpers.getRegisterController().pushText('"', 'yank', '\t\tabc\n\t\t\tdef\n', true); - helpers.doKeys(']', 'p'); - eq('\t___\n\tabc\n\t\tdef', cm.getValue()); -}, { value: '\t___', indentWithTabs: true}); -testVim(']p_with_spaces_translated_to_tabs', function(cm, vim, helpers) { - helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); - helpers.doKeys(']', 'p'); - eq('\t___\n\tabc\n\t\tdef', cm.getValue()); -}, { value: '\t___', indentWithTabs: true, tabSize: 2 }); -testVim('[p', function(cm, vim, helpers) { - helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); - helpers.doKeys('[', 'p'); - eq(' abc\n def\n ___', cm.getValue()); -}, { value: ' ___' }); -testVim('P', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false); - helpers.doKeys('P'); - eq('_abc\ndef__', cm.getValue()); - helpers.assertCursorAt(1, 3); -}, { value: '___' }); -testVim('P_line', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true); - helpers.doKeys('2', 'P'); - eq(' a\nd\n a\nd\n___', cm.getValue()); - helpers.assertCursorAt(0, 2); -}, { value: '___' }); -testVim('r', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('3', 'r', 'u'); - eq('wuuuet\nanother', cm.getValue(),'3r failed'); - helpers.assertCursorAt(0, 3); - cm.setCursor(0, 4); - helpers.doKeys('v', 'j', 'h', 'r', ''); - eq('wuuu \n her', cm.getValue(),'Replacing selection by space-characters failed'); - if (isAce) return; - cm.setValue("ox"); - helpers.doKeys('r', ''); - eq('ox', cm.getValue()); - helpers.doKeys('r', ''); - eq('ox', cm.getValue()); - helpers.doKeys('r', ''); - eq('\nx', cm.getValue()); -}, { value: 'wordet\nanother' }); -testVim('r_visual_block', function(cm, vim, helpers) { - cm.setOption("tabSize", 4); - cm.setCursor(2, 3); - helpers.doKeys('', 'k', 'k', 'h', 'h', 'r', 'l'); - eq('1lll\n5lll\nalllefg', cm.getValue()); - helpers.doKeys('', 'l', 'j', 'r', ''); - eq('1 l\n5 l\nalllefg', cm.getValue()); - cm.setCursor(2, 0); - helpers.doKeys('o'); - helpers.doKeys(''); - cm.replaceRange('\t\t', cm.getCursor()); - helpers.doKeys('', 'h', 'h', 'r', 'r'); - eq('1 l\n5 l\nalllefg\nrrrrrrrr', cm.getValue()); -}, {value: '1234\n5678\nabcdefg'}); -testVim('R', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('R'); - helpers.assertCursorAt(0, 1); - eq('vim-replace', cm.getOption('keyMap')); - is(cm.state.overwrite, 'Setting overwrite state failed'); -}); -testVim('mark', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 't'); - cm.setCursor(0, 0); - helpers.doKeys('`', 't'); - helpers.assertCursorAt(2, 2); - cm.setCursor(2, 0); - cm.replaceRange(' h', cm.getCursor()); - cm.setCursor(0, 0); - helpers.doKeys('\'', 't'); - helpers.assertCursorAt(2, 3); -}); -isAce || testVim('mark\'', function(cm, vim, helpers) { - cm.setCursor(2, 2); - cm.setCursor(0, 0); - helpers.doKeys('`', '\''); - helpers.assertCursorAt(2, 2); - cm.setCursor(2, 0); - cm.replaceRange(' h', cm.getCursor()); - cm.setCursor(0, 0); - helpers.doKeys('\'', '\''); - helpers.assertCursorAt(2, 3); -}); -isAce || testVim('mark.', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('O', 'testing', ''); - cm.setCursor(3, 3); - helpers.doKeys('\'', '.'); - helpers.assertCursorAt(0, 0); - cm.setCursor(4, 4); - helpers.doKeys('`', '.'); - helpers.assertCursorAt(0, 6); -}); -testVim('jumpToMark_next', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 't'); - cm.setCursor(0, 0); - helpers.doKeys(']', '`'); - helpers.assertCursorAt(2, 2); - cm.setCursor(0, 0); - helpers.doKeys(']', '\''); - helpers.assertCursorAt(2, 0); -}); -testVim('jumpToMark_next_repeat', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 'a'); - cm.setCursor(3, 2); - helpers.doKeys('m', 'b'); - cm.setCursor(4, 2); - helpers.doKeys('m', 'c'); - cm.setCursor(0, 0); - helpers.doKeys('2', ']', '`'); - helpers.assertCursorAt(3, 2); - cm.setCursor(0, 0); - helpers.doKeys('2', ']', '\''); - helpers.assertCursorAt(3, 1); -}); -testVim('jumpToMark_next_sameline', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('m', 'a'); - cm.setCursor(2, 4); - helpers.doKeys('m', 'b'); - cm.setCursor(2, 2); - helpers.doKeys(']', '`'); - helpers.assertCursorAt(2, 4); -}); -testVim('jumpToMark_next_onlyprev', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('m', 'a'); - cm.setCursor(4, 0); - helpers.doKeys(']', '`'); - helpers.assertCursorAt(4, 0); -}); -testVim('jumpToMark_next_nomark', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys(']', '`'); - helpers.assertCursorAt(2, 2); - helpers.doKeys(']', '\''); - helpers.assertCursorAt(2, 0); -}); -testVim('jumpToMark_next_linewise_over', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 'a'); - cm.setCursor(3, 4); - helpers.doKeys('m', 'b'); - cm.setCursor(2, 1); - helpers.doKeys(']', '\''); - helpers.assertCursorAt(3, 1); -}); -testVim('jumpToMark_next_action', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 't'); - cm.setCursor(0, 0); - helpers.doKeys('d', ']', '`'); - helpers.assertCursorAt(0, 0); - var actual = cm.getLine(0); - var expected = 'pop pop 0 1 2 3 4'; - eq(actual, expected, "Deleting while jumping to the next mark failed."); -}); -testVim('jumpToMark_next_line_action', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 't'); - cm.setCursor(0, 0); - helpers.doKeys('d', ']', '\''); - helpers.assertCursorAt(0, 1); - var actual = cm.getLine(0); - var expected = ' (a) [b] {c} ' - eq(actual, expected, "Deleting while jumping to the next mark line failed."); -}); -testVim('jumpToMark_prev', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 't'); - cm.setCursor(4, 0); - helpers.doKeys('[', '`'); - helpers.assertCursorAt(2, 2); - cm.setCursor(4, 0); - helpers.doKeys('[', '\''); - helpers.assertCursorAt(2, 0); -}); -testVim('jumpToMark_prev_repeat', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 'a'); - cm.setCursor(3, 2); - helpers.doKeys('m', 'b'); - cm.setCursor(4, 2); - helpers.doKeys('m', 'c'); - cm.setCursor(5, 0); - helpers.doKeys('2', '[', '`'); - helpers.assertCursorAt(3, 2); - cm.setCursor(5, 0); - helpers.doKeys('2', '[', '\''); - helpers.assertCursorAt(3, 1); -}); -testVim('jumpToMark_prev_sameline', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('m', 'a'); - cm.setCursor(2, 4); - helpers.doKeys('m', 'b'); - cm.setCursor(2, 2); - helpers.doKeys('[', '`'); - helpers.assertCursorAt(2, 0); -}); -testVim('jumpToMark_prev_onlynext', function(cm, vim, helpers) { - cm.setCursor(4, 4); - helpers.doKeys('m', 'a'); - cm.setCursor(2, 0); - helpers.doKeys('[', '`'); - helpers.assertCursorAt(2, 0); -}); -testVim('jumpToMark_prev_nomark', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('[', '`'); - helpers.assertCursorAt(2, 2); - helpers.doKeys('[', '\''); - helpers.assertCursorAt(2, 0); -}); -testVim('jumpToMark_prev_linewise_over', function(cm, vim, helpers) { - cm.setCursor(2, 2); - helpers.doKeys('m', 'a'); - cm.setCursor(3, 4); - helpers.doKeys('m', 'b'); - cm.setCursor(3, 6); - helpers.doKeys('[', '\''); - helpers.assertCursorAt(2, 0); -}); -testVim('delmark_single', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('m', 't'); - helpers.doEx('delmarks t'); - cm.setCursor(0, 0); - helpers.doKeys('`', 't'); - helpers.assertCursorAt(0, 0); -}); -testVim('delmark_range', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('m', 'a'); - cm.setCursor(2, 2); - helpers.doKeys('m', 'b'); - cm.setCursor(3, 2); - helpers.doKeys('m', 'c'); - cm.setCursor(4, 2); - helpers.doKeys('m', 'd'); - cm.setCursor(5, 2); - helpers.doKeys('m', 'e'); - helpers.doEx('delmarks b-d'); - cm.setCursor(0, 0); - helpers.doKeys('`', 'a'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'b'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'c'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'd'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'e'); - helpers.assertCursorAt(5, 2); -}); -testVim('delmark_multi', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('m', 'a'); - cm.setCursor(2, 2); - helpers.doKeys('m', 'b'); - cm.setCursor(3, 2); - helpers.doKeys('m', 'c'); - cm.setCursor(4, 2); - helpers.doKeys('m', 'd'); - cm.setCursor(5, 2); - helpers.doKeys('m', 'e'); - helpers.doEx('delmarks bcd'); - cm.setCursor(0, 0); - helpers.doKeys('`', 'a'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'b'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'c'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'd'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'e'); - helpers.assertCursorAt(5, 2); -}); -testVim('delmark_multi_space', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('m', 'a'); - cm.setCursor(2, 2); - helpers.doKeys('m', 'b'); - cm.setCursor(3, 2); - helpers.doKeys('m', 'c'); - cm.setCursor(4, 2); - helpers.doKeys('m', 'd'); - cm.setCursor(5, 2); - helpers.doKeys('m', 'e'); - helpers.doEx('delmarks b c d'); - cm.setCursor(0, 0); - helpers.doKeys('`', 'a'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'b'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'c'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'd'); - helpers.assertCursorAt(1, 2); - helpers.doKeys('`', 'e'); - helpers.assertCursorAt(5, 2); -}); -testVim('delmark_all', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('m', 'a'); - cm.setCursor(2, 2); - helpers.doKeys('m', 'b'); - cm.setCursor(3, 2); - helpers.doKeys('m', 'c'); - cm.setCursor(4, 2); - helpers.doKeys('m', 'd'); - cm.setCursor(5, 2); - helpers.doKeys('m', 'e'); - helpers.doEx('delmarks a b-de'); - cm.setCursor(0, 0); - helpers.doKeys('`', 'a'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('`', 'b'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('`', 'c'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('`', 'd'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('`', 'e'); - helpers.assertCursorAt(0, 0); -}); -testVim('visual', function(cm, vim, helpers) { - helpers.doKeys('l', 'v', 'l', 'l'); - helpers.assertCursorAt(0, 4); - eqCursorPos(makeCursor(0, 1), cm.getCursor('anchor')); - helpers.doKeys('d'); - eq('15', cm.getValue()); -}, { value: '12345' }); -testVim('visual_yank', function(cm, vim, helpers) { - helpers.doKeys('v', '3', 'l', 'y'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('p'); - eq('aa te test for yank', cm.getValue()); -}, { value: 'a test for yank' }) -testVim('visual_w', function(cm, vim, helpers) { - helpers.doKeys('v', 'w'); - eq(cm.getSelection(), 'motion t'); -}, { value: 'motion test'}); -testVim('visual_initial_selection', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('v'); - cm.getSelection('n'); -}, { value: 'init'}); -testVim('visual_crossover_left', function(cm, vim, helpers) { - cm.setCursor(0, 2); - helpers.doKeys('v', 'l', 'h', 'h'); - cm.getSelection('ro'); -}, { value: 'cross'}); -testVim('visual_crossover_left', function(cm, vim, helpers) { - cm.setCursor(0, 2); - helpers.doKeys('v', 'h', 'l', 'l'); - cm.getSelection('os'); -}, { value: 'cross'}); -testVim('visual_crossover_up', function(cm, vim, helpers) { - cm.setCursor(3, 2); - helpers.doKeys('v', 'j', 'k', 'k'); - eqCursorPos(Pos(2, 2), cm.getCursor('head')); - eqCursorPos(Pos(3, 3), cm.getCursor('anchor')); - helpers.doKeys('k'); - eqCursorPos(Pos(1, 2), cm.getCursor('head')); - eqCursorPos(Pos(3, 3), cm.getCursor('anchor')); -}, { value: 'cross\ncross\ncross\ncross\ncross\n'}); -testVim('visual_crossover_down', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('v', 'k', 'j', 'j'); - eqCursorPos(Pos(2, 3), cm.getCursor('head')); - eqCursorPos(Pos(1, 2), cm.getCursor('anchor')); - helpers.doKeys('j'); - eqCursorPos(Pos(3, 3), cm.getCursor('head')); - eqCursorPos(Pos(1, 2), cm.getCursor('anchor')); -}, { value: 'cross\ncross\ncross\ncross\ncross\n'}); -testVim('visual_exit', function(cm, vim, helpers) { - helpers.doKeys('', 'l', 'j', 'j', ''); - eqCursorPos(cm.getCursor('anchor'), cm.getCursor('head')); - eq(vim.visualMode, false); -}, { value: 'hello\nworld\nfoo' }); -testVim('visual_line', function(cm, vim, helpers) { - helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd'); - eq(' 4\n 5', cm.getValue()); -}, { value: ' 1\n 2\n 3\n 4\n 5' }); -testVim('visual_block_move_to_eol', function(cm, vim, helpers) { - // moveToEol should move all block cursors to end of line - cm.setCursor(0, 0); - helpers.doKeys('', 'G', '$'); - var selections = cm.getSelections().join(); - eq('123,45,6', selections); - // Checks that with cursor at Infinity, finding words backwards still works. - helpers.doKeys('2', 'k', 'b'); - selections = cm.getSelections().join(); - eq('1', selections); -}, {value: '123\n45\n6'}); -testVim('visual_block_different_line_lengths', function(cm, vim, helpers) { - // test the block selection with lines of different length - // i.e. extending the selection - // till the end of the longest line. - helpers.doKeys('', 'l', 'j', 'j', '6', 'l', 'd'); - helpers.doKeys('d', 'd', 'd', 'd'); - eq('', cm.getValue()); -}, {value: '1234\n5678\nabcdefg'}); -testVim('visual_block_truncate_on_short_line', function(cm, vim, helpers) { - // check for left side selection in case - // of moving up to a shorter line. - cm.replaceRange('', cm.getCursor()); - cm.setCursor(3, 4); - helpers.doKeys('', 'l', 'k', 'k', 'd'); - eq('hello world\n{\ntis\nsa!', cm.getValue()); -}, {value: 'hello world\n{\nthis is\nsparta!'}); -testVim('visual_block_corners', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('', '2', 'l', 'k'); - // circle around the anchor - // and check the selections - var selections = cm.getSelections(); - eq('345891', selections.join('')); - helpers.doKeys('4', 'h'); - selections = cm.getSelections(); - eq('123678', selections.join('')); - helpers.doKeys('j', 'j'); - selections = cm.getSelections(); - eq('678abc', selections.join('')); - helpers.doKeys('4', 'l'); - selections = cm.getSelections(); - eq('891cde', selections.join('')); -}, {value: '12345\n67891\nabcde'}); -testVim('visual_block_mode_switch', function(cm, vim, helpers) { - // switch between visual modes - cm.setCursor(1, 1); - // blockwise to characterwise visual - helpers.doKeys('', 'j', 'l', 'v'); - var selections = cm.getSelections(); - eq('7891\nabc', selections.join('')); - // characterwise to blockwise - helpers.doKeys(''); - selections = cm.getSelections(); - eq('78bc', selections.join('')); - // blockwise to linewise visual - helpers.doKeys('V'); - selections = cm.getSelections(); - eq('67891\nabcde', selections.join('')); -}, {value: '12345\n67891\nabcde'}); -testVim('visual_block_crossing_short_line', function(cm, vim, helpers) { - // visual block with long and short lines - cm.setCursor(0, 3); - helpers.doKeys('', 'j', 'j', 'j'); - var selections = cm.getSelections().join(); - eq('4,,d,b', selections); - helpers.doKeys('3', 'k'); - selections = cm.getSelections().join(); - eq('4', selections); - helpers.doKeys('5', 'j', 'k'); - selections = cm.getSelections().join(""); - eq(10, selections.length); -}, {value: '123456\n78\nabcdefg\nfoobar\n}\n'}); -testVim('visual_block_curPos_on_exit', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('', '3' , 'l', ''); - eqCursorPos(makeCursor(0, 3), cm.getCursor()); - helpers.doKeys('h', '', '2' , 'j' ,'3' , 'l'); - eq(cm.getSelections().join(), "3456,,cdef"); - helpers.doKeys('4' , 'h'); - eq(cm.getSelections().join(), "23,8,bc"); - helpers.doKeys('2' , 'l'); - eq(cm.getSelections().join(), "34,,cd"); -}, {value: '123456\n78\nabcdefg\nfoobar'}); - -testVim('visual_marks', function(cm, vim, helpers) { - helpers.doKeys('l', 'v', 'l', 'l', 'j', 'j', 'v'); - // Test visual mode marks - cm.setCursor(2, 1); - helpers.doKeys('\'', '<'); - helpers.assertCursorAt(0, 1); - helpers.doKeys('\'', '>'); - helpers.assertCursorAt(2, 0); -}); -testVim('visual_join', function(cm, vim, helpers) { - helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J'); - eq(' 1 2 3\n 4\n 5', cm.getValue()); - is(!vim.visualMode); -}, { value: ' 1\n 2\n 3\n 4\n 5' }); -testVim('visual_join_2', function(cm, vim, helpers) { - helpers.doKeys('G', 'V', 'g', 'g', 'J'); - eq('1 2 3 4 5 6 ', cm.getValue()); - is(!vim.visualMode); -}, { value: '1\n2\n3\n4\n5\n6\n'}); -testVim('visual_blank', function(cm, vim, helpers) { - helpers.doKeys('v', 'k'); - eq(vim.visualMode, true); -}, { value: '\n' }); -testVim('reselect_visual', function(cm, vim, helpers) { - helpers.doKeys('l', 'v', 'l', 'l', 'l', 'y', 'g', 'v'); - helpers.assertCursorAt(0, 5); - eqCursorPos(makeCursor(0, 1), cm.getCursor('anchor')); - helpers.doKeys('v'); - cm.setCursor(1, 0); - helpers.doKeys('v', 'l', 'l', 'p'); - eq('123456\n2345\nbar', cm.getValue()); - cm.setCursor(0, 0); - helpers.doKeys('g', 'v'); - // here the fake cursor is at (1, 3) - helpers.assertCursorAt(1, 4); - eqCursorPos(makeCursor(1, 0), cm.getCursor('anchor')); - helpers.doKeys('v'); - cm.setCursor(2, 0); - helpers.doKeys('v', 'l', 'l', 'g', 'v'); - helpers.assertCursorAt(1, 4); - eqCursorPos(makeCursor(1, 0), cm.getCursor('anchor')); - helpers.doKeys('g', 'v'); - helpers.assertCursorAt(2, 3); - eqCursorPos(makeCursor(2, 0), cm.getCursor('anchor')); - eq('123456\n2345\nbar', cm.getValue()); -}, { value: '123456\nfoo\nbar' }); -testVim('reselect_visual_line', function(cm, vim, helpers) { - helpers.doKeys('l', 'V', 'j', 'j', 'V', 'g', 'v', 'd'); - eq('foo\nand\nbar', cm.getValue()); - cm.setCursor(1, 0); - helpers.doKeys('V', 'y', 'j'); - helpers.doKeys('V', 'p' , 'g', 'v', 'd'); - eq('foo\nand', cm.getValue()); -}, { value: 'hello\nthis\nis\nfoo\nand\nbar' }); -testVim('reselect_visual_block', function(cm, vim, helpers) { - cm.setCursor(1, 2); - helpers.doKeys('', 'k', 'h', ''); - cm.setCursor(2, 1); - helpers.doKeys('v', 'l', 'g', 'v'); - eqCursorPos(Pos(1, 2), vim.sel.anchor); - eqCursorPos(Pos(0, 1), vim.sel.head); - // Ensure selection is done with visual block mode rather than one - // continuous range. - eq(cm.getSelections().join(''), '23oo') - helpers.doKeys('g', 'v'); - eqCursorPos(Pos(2, 1), vim.sel.anchor); - eqCursorPos(Pos(2, 2), vim.sel.head); - helpers.doKeys(''); - // Ensure selection of deleted range - cm.setCursor(1, 1); - helpers.doKeys('v', '', 'j', 'd', 'g', 'v'); - eq(cm.getSelections().join(''), 'or'); -}, { value: '123456\nfoo\nbar' }); -testVim('s_normal', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('s'); - helpers.doKeys(''); - eq('ac', cm.getValue()); -}, { value: 'abc'}); -testVim('s_visual', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('v', 's'); - helpers.doKeys(''); - helpers.assertCursorAt(0, 0); - eq('ac', cm.getValue()); -}, { value: 'abc'}); -testVim('o_visual', function(cm, vim, helpers) { - cm.setCursor(0,0); - helpers.doKeys('v','l','l','l','o'); - helpers.assertCursorAt(0,0); - helpers.doKeys('v','v','j','j','j','o'); - helpers.assertCursorAt(0,0); - helpers.doKeys('O'); - helpers.doKeys('l','l') - helpers.assertCursorAt(3, 3); - helpers.doKeys('d'); - eq('p',cm.getValue()); -}, { value: 'abcd\nefgh\nijkl\nmnop'}); -testVim('o_visual_block', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('','3','j','l','l', 'o'); - eqCursorPos(Pos(3, 3), vim.sel.anchor); - eqCursorPos(Pos(0, 1), vim.sel.head); - helpers.doKeys('O'); - eqCursorPos(Pos(3, 1), vim.sel.anchor); - eqCursorPos(Pos(0, 3), vim.sel.head); - helpers.doKeys('o'); - eqCursorPos(Pos(0, 3), vim.sel.anchor); - eqCursorPos(Pos(3, 1), vim.sel.head); -}, { value: 'abcd\nefgh\nijkl\nmnop'}); -testVim('changeCase_visual', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('v', 'l', 'l'); - helpers.doKeys('U'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('v', 'l', 'l'); - helpers.doKeys('u'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('l', 'l', 'l', '.'); - helpers.assertCursorAt(0, 3); - cm.setCursor(0, 0); - helpers.doKeys('q', 'a', 'v', 'j', 'U', 'q'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('j', '@', 'a'); - helpers.assertCursorAt(1, 0); - cm.setCursor(3, 0); - helpers.doKeys('V', 'U', 'j', '.'); - eq('ABCDEF\nGHIJKL\nMnopq\nSHORT LINE\nLONG LINE OF TEXT', cm.getValue()); -}, { value: 'abcdef\nghijkl\nmnopq\nshort line\nlong line of text'}); -testVim('changeCase_visual_block', function(cm, vim, helpers) { - cm.setCursor(2, 1); - helpers.doKeys('', 'k', 'k', 'h', 'U'); - eq('ABcdef\nGHijkl\nMNopq\nfoo', cm.getValue()); - cm.setCursor(0, 2); - helpers.doKeys('.'); - eq('ABCDef\nGHIJkl\nMNOPq\nfoo', cm.getValue()); - // check when last line is shorter. - cm.setCursor(2, 2); - helpers.doKeys('.'); - eq('ABCDef\nGHIJkl\nMNOPq\nfoO', cm.getValue()); -}, { value: 'abcdef\nghijkl\nmnopq\nfoo'}); -testVim('visual_paste', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('v', 'l', 'l', 'y'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('3', 'l', 'j', 'v', 'l', 'p'); - helpers.assertCursorAt(1, 5); - eq('this is a\nunithitest for visual paste', cm.getValue()); - cm.setCursor(0, 0); - // in case of pasting whole line - helpers.doKeys('y', 'y'); - cm.setCursor(1, 6); - helpers.doKeys('v', 'l', 'l', 'l', 'p'); - helpers.assertCursorAt(2, 0); - eq('this is a\nunithi\nthis is a\n for visual paste', cm.getValue()); -}, { value: 'this is a\nunit test for visual paste'}); - -// This checks the contents of the register used to paste the text -testVim('v_paste_from_register', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('"', 'a', 'y', 'w'); - cm.setCursor(1, 0); - helpers.doKeys('v', 'p'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/a\s+register/.test(text)); - }); -}, { value: 'register contents\nare not erased'}); -testVim('S_normal', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('j', 'S'); - helpers.doKeys(''); - helpers.assertCursorAt(1, 1); - eq('aa{\n \ncc', cm.getValue()); - helpers.doKeys('j', 'S'); - eq('aa{\n \n ', cm.getValue()); - helpers.assertCursorAt(2, 2); - helpers.doKeys(''); - helpers.doKeys('d', 'd', 'd', 'd'); - helpers.assertCursorAt(0, 0); - helpers.doKeys('S'); - is(vim.insertMode); - eq('', cm.getValue()); -}, { value: 'aa{\nbb\ncc'}); -testVim('blockwise_paste', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('', '3', 'j', 'l', 'y'); - cm.setCursor(0, 2); - // paste one char after the current cursor position - helpers.doKeys('p'); - eq('helhelo\nworwold\nfoofo\nbarba', cm.getValue()); - cm.setCursor(0, 0); - helpers.doKeys('v', '4', 'l', 'y'); - cm.setCursor(0, 0); - helpers.doKeys('', '3', 'j', 'p'); - eq('helheelhelo\norwold\noofo\narba', cm.getValue()); -}, { value: 'hello\nworld\nfoo\nbar'}); -testVim('blockwise_paste_long/short_line', function(cm, vim, helpers) { - // extend short lines in case of different line lengths. - cm.setCursor(0, 0); - helpers.doKeys('', 'j', 'j', 'y'); - cm.setCursor(0, 3); - helpers.doKeys('p'); - eq('hellho\nfoo f\nbar b', cm.getValue()); -}, { value: 'hello\nfoo\nbar'}); -testVim('blockwise_paste_cut_paste', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('', '2', 'j', 'x'); - cm.setCursor(0, 0); - helpers.doKeys('P'); - eq('cut\nand\npaste\nme', cm.getValue()); -}, { value: 'cut\nand\npaste\nme'}); -testVim('blockwise_paste_from_register', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('', '2', 'j', '"', 'a', 'y'); - cm.setCursor(0, 3); - helpers.doKeys('"', 'a', 'p'); - eq('foobfar\nhellho\nworlwd', cm.getValue()); -}, { value: 'foobar\nhello\nworld'}); -testVim('blockwise_paste_last_line', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('', '2', 'j', 'l', 'y'); - cm.setCursor(3, 0); - helpers.doKeys('p'); - eq('cut\nand\npaste\nmcue\n an\n pa', cm.getValue()); -}, { value: 'cut\nand\npaste\nme'}); - -testVim('S_visual', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('v', 'j', 'S'); - helpers.doKeys(''); - helpers.assertCursorAt(0, 0); - eq('\ncc', cm.getValue()); -}, { value: 'aa\nbb\ncc'}); - -testVim('d_/', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('match'); - helpers.doKeys('2', 'd', '/'); - helpers.assertCursorAt(0, 0); - eq('match \n next', cm.getValue()); - cm.openDialog = helpers.fakeOpenDialog('2'); - helpers.doKeys('d', ':'); - // TODO eq(' next', cm.getValue()); -}, { value: 'text match match \n next' }); -testVim('/ and n/N', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('match'); - helpers.doKeys('/'); - helpers.assertCursorAt(0, 11); - helpers.doKeys('n'); - helpers.assertCursorAt(1, 6); - helpers.doKeys('N'); - helpers.assertCursorAt(0, 11); - - cm.setCursor(0, 0); - helpers.doKeys('2', '/'); - helpers.assertCursorAt(1, 6); -}, { value: 'match nope match \n nope Match' }); -testVim('/_case', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('Match'); - helpers.doKeys('/'); - helpers.assertCursorAt(1, 6); -}, { value: 'match nope match \n nope Match' }); -testVim('/_2_pcre', function(cm, vim, helpers) { - CodeMirror.Vim.setOption('pcre', true); - cm.openDialog = helpers.fakeOpenDialog('(word){2}'); - helpers.doKeys('/'); - helpers.assertCursorAt(1, 9); - helpers.doKeys('n'); - helpers.assertCursorAt(2, 1); -}, { value: 'word\n another wordword\n wordwordword\n' }); -testVim('/_2_nopcre', function(cm, vim, helpers) { - CodeMirror.Vim.setOption('pcre', false); - cm.openDialog = helpers.fakeOpenDialog('\\(word\\)\\{2}'); - helpers.doKeys('/'); - helpers.assertCursorAt(1, 9); - helpers.doKeys('n'); - helpers.assertCursorAt(2, 1); -}, { value: 'word\n another wordword\n wordwordword\n' }); -testVim('/_nongreedy', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('aa'); - helpers.doKeys('/'); - helpers.assertCursorAt(0, 4); - helpers.doKeys('n'); - helpers.assertCursorAt(1, 3); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 0); -}, { value: 'aaa aa \n a aa'}); -testVim('?_nongreedy', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('aa'); - helpers.doKeys('?'); - helpers.assertCursorAt(1, 3); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 4); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 0); -}, { value: 'aaa aa \n a aa'}); -testVim('/_greedy', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('a+'); - helpers.doKeys('/'); - helpers.assertCursorAt(0, 4); - helpers.doKeys('n'); - helpers.assertCursorAt(1, 1); - helpers.doKeys('n'); - helpers.assertCursorAt(1, 3); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 0); -}, { value: 'aaa aa \n a aa'}); -testVim('?_greedy', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('a+'); - helpers.doKeys('?'); - helpers.assertCursorAt(1, 3); - helpers.doKeys('n'); - helpers.assertCursorAt(1, 1); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 4); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 0); -}, { value: 'aaa aa \n a aa'}); -testVim('/_greedy_0_or_more', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('a*'); - helpers.doKeys('/'); - helpers.assertCursorAt(0, 3); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 4); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 5); - helpers.doKeys('n'); - helpers.assertCursorAt(1, 0); - helpers.doKeys('n'); - helpers.assertCursorAt(1, 1); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 0); -}, { value: 'aaa aa\n aa'}); -testVim('?_greedy_0_or_more', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('a*'); - helpers.doKeys('?'); - helpers.assertCursorAt(1, 1); - helpers.doKeys('n'); - helpers.assertCursorAt(1, 0); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 5); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 4); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 3); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 0); -}, { value: 'aaa aa\n aa'}); -testVim('? and n/N', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('match'); - helpers.doKeys('?'); - helpers.assertCursorAt(1, 6); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 11); - helpers.doKeys('N'); - helpers.assertCursorAt(1, 6); - - cm.setCursor(0, 0); - helpers.doKeys('2', '?'); - helpers.assertCursorAt(0, 11); -}, { value: 'match nope match \n nope Match' }); -testVim('*', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('*'); - helpers.assertCursorAt(0, 22); - - cm.setCursor(0, 9); - helpers.doKeys('2', '*'); - helpers.assertCursorAt(1, 8); -}, { value: 'nomatch match nomatch match \nnomatch Match' }); -testVim('*_no_word', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('*'); - helpers.assertCursorAt(0, 0); -}, { value: ' \n match \n' }); -testVim('*_symbol', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('*'); - helpers.assertCursorAt(1, 0); -}, { value: ' /}\n/} match \n' }); -testVim('#', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('#'); - helpers.assertCursorAt(1, 8); - - cm.setCursor(0, 9); - helpers.doKeys('2', '#'); - helpers.assertCursorAt(0, 22); -}, { value: 'nomatch match nomatch match \nnomatch Match' }); -testVim('*_seek', function(cm, vim, helpers) { - // Should skip over space and symbols. - cm.setCursor(0, 3); - helpers.doKeys('*'); - helpers.assertCursorAt(0, 22); -}, { value: ' := match nomatch match \nnomatch Match' }); -testVim('#', function(cm, vim, helpers) { - // Should skip over space and symbols. - cm.setCursor(0, 3); - helpers.doKeys('#'); - helpers.assertCursorAt(1, 8); -}, { value: ' := match nomatch match \nnomatch Match' }); -testVim('g*', function(cm, vim, helpers) { - cm.setCursor(0, 8); - helpers.doKeys('g', '*'); - helpers.assertCursorAt(0, 18); - cm.setCursor(0, 8); - helpers.doKeys('3', 'g', '*'); - helpers.assertCursorAt(1, 8); -}, { value: 'matches match alsoMatch\nmatchme matching' }); -testVim('g#', function(cm, vim, helpers) { - cm.setCursor(0, 8); - helpers.doKeys('g', '#'); - helpers.assertCursorAt(0, 0); - cm.setCursor(0, 8); - helpers.doKeys('3', 'g', '#'); - helpers.assertCursorAt(1, 0); -}, { value: 'matches match alsoMatch\nmatchme matching' }); -testVim('macro_insert', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'a', '0', 'i'); - cm.replaceRange('foo', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('q', '@', 'a'); - eq('foofoo', cm.getValue()); -}, { value: ''}); -testVim('macro_insert_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'a', '$', 'a'); - cm.replaceRange('larry.', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('a'); - cm.replaceRange('curly.', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('q'); - helpers.doKeys('a'); - cm.replaceRange('moe.', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('@', 'a'); - // At this point, the most recent edit should be the 2nd insert change - // inside the macro, i.e. "curly.". - helpers.doKeys('.'); - eq('larry.curly.moe.larry.curly.curly.', cm.getValue()); -}, { value: ''}); -testVim('macro_space', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('', ''); - helpers.assertCursorAt(0, 2); - helpers.doKeys('q', 'a', '', '', 'q'); - helpers.assertCursorAt(0, 4); - helpers.doKeys('@', 'a'); - helpers.assertCursorAt(0, 6); - helpers.doKeys('@', 'a'); - helpers.assertCursorAt(0, 8); -}, { value: 'one line of text.'}); -testVim('macro_t_search', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'a', 't', 'e', 'q'); - helpers.assertCursorAt(0, 1); - helpers.doKeys('l', '@', 'a'); - helpers.assertCursorAt(0, 6); - helpers.doKeys('l', ';'); - helpers.assertCursorAt(0, 12); -}, { value: 'one line of text.'}); -testVim('macro_f_search', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'b', 'f', 'e', 'q'); - helpers.assertCursorAt(0, 2); - helpers.doKeys('@', 'b'); - helpers.assertCursorAt(0, 7); - helpers.doKeys(';'); - helpers.assertCursorAt(0, 13); -}, { value: 'one line of text.'}); -testVim('macro_slash_search', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'c'); - cm.openDialog = helpers.fakeOpenDialog('e'); - helpers.doKeys('/', 'q'); - helpers.assertCursorAt(0, 2); - helpers.doKeys('@', 'c'); - helpers.assertCursorAt(0, 7); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 13); -}, { value: 'one line of text.'}); -testVim('macro_multislash_search', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'd'); - cm.openDialog = helpers.fakeOpenDialog('e'); - helpers.doKeys('/'); - cm.openDialog = helpers.fakeOpenDialog('t'); - helpers.doKeys('/', 'q'); - helpers.assertCursorAt(0, 12); - helpers.doKeys('@', 'd'); - helpers.assertCursorAt(0, 15); -}, { value: 'one line of text to rule them all.'}); -testVim('macro_last_ex_command_register', function (cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doEx('s/a/b'); - helpers.doKeys('2', '@', ':'); - eq('bbbaa', cm.getValue()); - helpers.assertCursorAt(0, 2); -}, { value: 'aaaaa'}); -testVim('macro_parens', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'z', 'i'); - cm.replaceRange('(', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('e', 'a'); - cm.replaceRange(')', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('q'); - helpers.doKeys('w', '@', 'z'); - helpers.doKeys('w', '@', 'z'); - eq('(see) (spot) (run)', cm.getValue()); -}, { value: 'see spot run'}); -testVim('macro_overwrite', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'z', '0', 'i'); - cm.replaceRange('I ', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('q'); - helpers.doKeys('e'); - // Now replace the macro with something else. - helpers.doKeys('q', 'z', 'a'); - cm.replaceRange('.', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('q'); - helpers.doKeys('e', '@', 'z'); - helpers.doKeys('e', '@', 'z'); - eq('I see. spot. run.', cm.getValue()); -}, { value: 'see spot run'}); -testVim('macro_search_f', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'a', 'f', ' '); - helpers.assertCursorAt(0,3); - helpers.doKeys('q', '0'); - helpers.assertCursorAt(0,0); - helpers.doKeys('@', 'a'); - helpers.assertCursorAt(0,3); -}, { value: 'The quick brown fox jumped over the lazy dog.'}); -testVim('macro_search_2f', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'a', '2', 'f', ' '); - helpers.assertCursorAt(0,9); - helpers.doKeys('q', '0'); - helpers.assertCursorAt(0,0); - helpers.doKeys('@', 'a'); - helpers.assertCursorAt(0,9); -}, { value: 'The quick brown fox jumped over the lazy dog.'}); -testVim('macro_yank_tick', function(cm, vim, helpers) { - cm.setCursor(0, 0); - // Start recording a macro into the \' register. - helpers.doKeys('q', '\''); - helpers.doKeys('y', '', '', '', '', 'p'); - helpers.assertCursorAt(0,4); - eq('the tex parrot', cm.getValue()); -}, { value: 'the ex parrot'}); -testVim('yank_register', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('"', 'a', 'y', 'y'); - helpers.doKeys('j', '"', 'b', 'y', 'y'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/a\s+foo/.test(text)); - is(/b\s+bar/.test(text)); - }); - helpers.doKeys(':'); -}, { value: 'foo\nbar'}); -testVim('yank_visual_block', function(cm, vim, helpers) { - cm.setCursor(0, 1); - helpers.doKeys('', 'l', 'j', '"', 'a', 'y'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/a\s+oo\nar/.test(text)); - }); - helpers.doKeys(':'); -}, { value: 'foo\nbar'}); -testVim('yank_append_line_to_line_register', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('"', 'a', 'y', 'y'); - helpers.doKeys('j', '"', 'A', 'y', 'y'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/a\s+foo\nbar/.test(text)); - is(/"\s+foo\nbar/.test(text)); - }); - helpers.doKeys(':'); -}, { value: 'foo\nbar'}); -testVim('yank_append_word_to_word_register', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('"', 'a', 'y', 'w'); - helpers.doKeys('j', '"', 'A', 'y', 'w'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/a\s+foobar/.test(text)); - is(/"\s+foobar/.test(text)); - }); - helpers.doKeys(':'); -}, { value: 'foo\nbar'}); -testVim('yank_append_line_to_word_register', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('"', 'a', 'y', 'w'); - helpers.doKeys('j', '"', 'A', 'y', 'y'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/a\s+foo\nbar/.test(text)); - is(/"\s+foo\nbar/.test(text)); - }); - helpers.doKeys(':'); -}, { value: 'foo\nbar'}); -testVim('yank_append_word_to_line_register', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('"', 'a', 'y', 'y'); - helpers.doKeys('j', '"', 'A', 'y', 'w'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/a\s+foo\nbar/.test(text)); - is(/"\s+foo\nbar/.test(text)); - }); - helpers.doKeys(':'); -}, { value: 'foo\nbar'}); -testVim('macro_register', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('q', 'a', 'i'); - cm.replaceRange('gangnam', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('q'); - helpers.doKeys('q', 'b', 'o'); - cm.replaceRange('style', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('q'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/a\s+i/.test(text)); - is(/b\s+o/.test(text)); - }); - helpers.doKeys(':'); -}, { value: ''}); -testVim('._register', function(cm,vim,helpers) { - cm.setCursor(0,0); - helpers.doKeys('i'); - cm.replaceRange('foo',cm.getCursor()); - helpers.doKeys(''); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/\.\s+foo/.test(text)); - }); - helpers.doKeys(':'); -}, {value: ''}); -testVim(':_register', function(cm,vim,helpers) { - helpers.doEx('bar'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/:\s+bar/.test(text)); - }); - helpers.doKeys(':'); -}, {value: ''}); -testVim('search_register_escape', function(cm, vim, helpers) { - // Check that the register is restored if the user escapes rather than confirms. - cm.openDialog = helpers.fakeOpenDialog('waldo'); - helpers.doKeys('/'); - var onKeyDown; - var onKeyUp; - var KEYCODES = { - f: 70, - o: 79, - Esc: 27 - }; - cm.openDialog = function(template, callback, options) { - onKeyDown = options.onKeyDown; - onKeyUp = options.onKeyUp; - }; - var close = function() {}; - helpers.doKeys('/'); - // Fake some keyboard events coming in. - onKeyDown({keyCode: KEYCODES.f}, '', close); - onKeyUp({keyCode: KEYCODES.f}, '', close); - onKeyDown({keyCode: KEYCODES.o}, 'f', close); - onKeyUp({keyCode: KEYCODES.o}, 'f', close); - onKeyDown({keyCode: KEYCODES.o}, 'fo', close); - onKeyUp({keyCode: KEYCODES.o}, 'fo', close); - onKeyDown({keyCode: KEYCODES.Esc}, 'foo', close); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/waldo/.test(text)); - is(!/foo/.test(text)); - }); - helpers.doKeys(':'); -}, {value: ''}); -testVim('search_register', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('foo'); - helpers.doKeys('/'); - cm.openDialog = helpers.fakeOpenDialog('registers'); - cm.openNotification = helpers.fakeOpenNotification(function(text) { - is(/\/\s+foo/.test(text)); - }); - helpers.doKeys(':'); -}, {value: ''}); -testVim('search_history', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('this'); - helpers.doKeys('/'); - cm.openDialog = helpers.fakeOpenDialog('checks'); - helpers.doKeys('/'); - cm.openDialog = helpers.fakeOpenDialog('search'); - helpers.doKeys('/'); - cm.openDialog = helpers.fakeOpenDialog('history'); - helpers.doKeys('/'); - cm.openDialog = helpers.fakeOpenDialog('checks'); - helpers.doKeys('/'); - var onKeyDown; - var onKeyUp; - var query = ''; - var keyCodes = { - Up: 38, - Down: 40 - }; - cm.openDialog = function(template, callback, options) { - onKeyUp = options.onKeyUp; - onKeyDown = options.onKeyDown; - }; - var close = function(newVal) { - if (typeof newVal == 'string') query = newVal; - } - helpers.doKeys('/'); - onKeyDown({keyCode: keyCodes.Up}, query, close); - onKeyUp({keyCode: keyCodes.Up}, query, close); - eq(query, 'checks'); - onKeyDown({keyCode: keyCodes.Up}, query, close); - onKeyUp({keyCode: keyCodes.Up}, query, close); - eq(query, 'history'); - onKeyDown({keyCode: keyCodes.Up}, query, close); - onKeyUp({keyCode: keyCodes.Up}, query, close); - eq(query, 'search'); - onKeyDown({keyCode: keyCodes.Up}, query, close); - onKeyUp({keyCode: keyCodes.Up}, query, close); - eq(query, 'this'); - onKeyDown({keyCode: keyCodes.Down}, query, close); - onKeyUp({keyCode: keyCodes.Down}, query, close); - eq(query, 'search'); -}, {value: ''}); -testVim('exCommand_history', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('registers'); - helpers.doKeys(':'); - cm.openDialog = helpers.fakeOpenDialog('sort'); - helpers.doKeys(':'); - cm.openDialog = helpers.fakeOpenDialog('map'); - helpers.doKeys(':'); - cm.openDialog = helpers.fakeOpenDialog('invalid'); - helpers.doKeys(':'); - var onKeyDown; - var onKeyUp; - var input = ''; - var keyCodes = { - Up: 38, - Down: 40, - s: 115 - }; - cm.openDialog = function(template, callback, options) { - onKeyUp = options.onKeyUp; - onKeyDown = options.onKeyDown; - }; - var close = function(newVal) { - if (typeof newVal == 'string') input = newVal; - } - helpers.doKeys(':'); - onKeyDown({keyCode: keyCodes.Up}, input, close); - eq(input, 'invalid'); - onKeyDown({keyCode: keyCodes.Up}, input, close); - eq(input, 'map'); - onKeyDown({keyCode: keyCodes.Up}, input, close); - eq(input, 'sort'); - onKeyDown({keyCode: keyCodes.Up}, input, close); - eq(input, 'registers'); - onKeyDown({keyCode: keyCodes.s}, '', close); - input = 's'; - onKeyDown({keyCode: keyCodes.Up}, input, close); - eq(input, 'sort'); -}, {value: ''}); -testVim('search_clear', function(cm, vim, helpers) { - var onKeyDown; - var input = ''; - var keyCodes = { - Ctrl: 17, - u: 85 - }; - cm.openDialog = function(template, callback, options) { - onKeyDown = options.onKeyDown; - }; - var close = function(newVal) { - if (typeof newVal == 'string') input = newVal; - } - helpers.doKeys('/'); - input = 'foo'; - onKeyDown({keyCode: keyCodes.Ctrl}, input, close); - onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close); - eq(input, ''); -}); -testVim('exCommand_clear', function(cm, vim, helpers) { - var onKeyDown; - var input = ''; - var keyCodes = { - Ctrl: 17, - u: 85 - }; - cm.openDialog = function(template, callback, options) { - onKeyDown = options.onKeyDown; - }; - var close = function(newVal) { - if (typeof newVal == 'string') input = newVal; - } - helpers.doKeys(':'); - input = 'foo'; - onKeyDown({keyCode: keyCodes.Ctrl}, input, close); - onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close); - eq(input, ''); -}); -testVim('.', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('2', 'd', 'w'); - helpers.doKeys('.'); - eq('5 6', cm.getValue()); -}, { value: '1 2 3 4 5 6'}); -testVim('._repeat', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('2', 'd', 'w'); - helpers.doKeys('3', '.'); - eq('6', cm.getValue()); -}, { value: '1 2 3 4 5 6'}); -testVim('._insert', function(cm, vim, helpers) { - helpers.doKeys('i'); - cm.replaceRange('test', cm.getCursor()); - helpers.doKeys(''); - helpers.doKeys('.'); - eq('testestt', cm.getValue()); - helpers.assertCursorAt(0, 6); - helpers.doKeys('O'); - cm.replaceRange('xyz', cm.getCursor()); - helpers.doInsertModeKeys('Backspace'); - helpers.doInsertModeKeys('Down'); - helpers.doKeys(''); - helpers.doKeys('.'); - eq('xy\nxy\ntestestt', cm.getValue()); - helpers.assertCursorAt(1, 1); -}, { value: ''}); -testVim('._insert_repeat', function(cm, vim, helpers) { - helpers.doKeys('i'); - cm.replaceRange('test', cm.getCursor()); - cm.setCursor(0, 4); - helpers.doKeys(''); - helpers.doKeys('2', '.'); - eq('testesttestt', cm.getValue()); - helpers.assertCursorAt(0, 10); -}, { value: ''}); -testVim('._repeat_insert', function(cm, vim, helpers) { - helpers.doKeys('3', 'i'); - cm.replaceRange('te', cm.getCursor()); - cm.setCursor(0, 2); - helpers.doKeys(''); - helpers.doKeys('.'); - eq('tetettetetee', cm.getValue()); - helpers.assertCursorAt(0, 10); -}, { value: ''}); -testVim('._insert_o', function(cm, vim, helpers) { - helpers.doKeys('o'); - cm.replaceRange('z', cm.getCursor()); - cm.setCursor(1, 1); - helpers.doKeys(''); - helpers.doKeys('.'); - eq('\nz\nz', cm.getValue()); - helpers.assertCursorAt(2, 0); -}, { value: ''}); -testVim('._insert_o_repeat', function(cm, vim, helpers) { - helpers.doKeys('o'); - cm.replaceRange('z', cm.getCursor()); - helpers.doKeys(''); - cm.setCursor(1, 0); - helpers.doKeys('2', '.'); - eq('\nz\nz\nz', cm.getValue()); - helpers.assertCursorAt(3, 0); -}, { value: ''}); -testVim('._insert_o_indent', function(cm, vim, helpers) { - helpers.doKeys('o'); - cm.replaceRange('z', cm.getCursor()); - helpers.doKeys(''); - cm.setCursor(1, 2); - helpers.doKeys('.'); - eq('{\n z\n z', cm.getValue()); - helpers.assertCursorAt(2, 2); -}, { value: '{'}); -testVim('._insert_cw', function(cm, vim, helpers) { - helpers.doKeys('c', 'w'); - cm.replaceRange('test', cm.getCursor()); - helpers.doKeys(''); - cm.setCursor(0, 3); - helpers.doKeys('2', 'l'); - helpers.doKeys('.'); - eq('test test word3', cm.getValue()); - helpers.assertCursorAt(0, 8); -}, { value: 'word1 word2 word3' }); -testVim('._insert_cw_repeat', function(cm, vim, helpers) { - // For some reason, repeat cw in desktop VIM will does not repeat insert mode - // changes. Will conform to that behavior. - helpers.doKeys('c', 'w'); - cm.replaceRange('test', cm.getCursor()); - helpers.doKeys(''); - cm.setCursor(0, 4); - helpers.doKeys('l'); - helpers.doKeys('2', '.'); - eq('test test', cm.getValue()); - helpers.assertCursorAt(0, 8); -}, { value: 'word1 word2 word3' }); -testVim('._delete', function(cm, vim, helpers) { - cm.setCursor(0, 5); - helpers.doKeys('i'); - helpers.doInsertModeKeys('Backspace'); - helpers.doKeys(''); - helpers.doKeys('.'); - eq('zace', cm.getValue()); - helpers.assertCursorAt(0, 1); -}, { value: 'zabcde'}); -testVim('._delete_repeat', function(cm, vim, helpers) { - cm.setCursor(0, 6); - helpers.doKeys('i'); - helpers.doInsertModeKeys('Backspace'); - helpers.doKeys(''); - helpers.doKeys('2', '.'); - eq('zzce', cm.getValue()); - helpers.assertCursorAt(0, 1); -}, { value: 'zzabcde'}); -testVim('._visual_>', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('V', 'j', '>'); - cm.setCursor(2, 0) - helpers.doKeys('.'); - eq(' 1\n 2\n 3\n 4', cm.getValue()); - helpers.assertCursorAt(2, 2); -}, { value: '1\n2\n3\n4'}); -testVim('._replace_repeat', function(cm, vim, helpers) { - helpers.doKeys('R'); - cm.replaceRange('123', cm.getCursor(), offsetCursor(cm.getCursor(), 0, 3)); - cm.setCursor(0, 3); - helpers.doKeys(''); - helpers.doKeys('2', '.'); - eq('12123123\nabcdefg', cm.getValue()); - helpers.assertCursorAt(0, 7); - cm.setCursor(1, 0); - helpers.doKeys('.'); - eq('12123123\n123123g', cm.getValue()); - helpers.doKeys('l', '"', '.', 'p'); - eq('12123123\n123123g123', cm.getValue()); -}, { value: 'abcdef\nabcdefg'}); -testVim('f;', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('f', 'x'); - helpers.doKeys(';'); - helpers.doKeys('2', ';'); - eq(9, cm.getCursor().ch); -}, { value: '01x3xx678x'}); -testVim('F;', function(cm, vim, helpers) { - cm.setCursor(0, 8); - helpers.doKeys('F', 'x'); - helpers.doKeys(';'); - helpers.doKeys('2', ';'); - eq(2, cm.getCursor().ch); -}, { value: '01x3xx6x8x'}); -testVim('t;', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('t', 'x'); - helpers.doKeys(';'); - helpers.doKeys('2', ';'); - eq(8, cm.getCursor().ch); -}, { value: '01x3xx678x'}); -testVim('T;', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('T', 'x'); - helpers.doKeys(';'); - helpers.doKeys('2', ';'); - eq(2, cm.getCursor().ch); -}, { value: '0xx3xx678x'}); -testVim('f,', function(cm, vim, helpers) { - cm.setCursor(0, 6); - helpers.doKeys('f', 'x'); - helpers.doKeys(','); - helpers.doKeys('2', ','); - eq(2, cm.getCursor().ch); -}, { value: '01x3xx678x'}); -testVim('F,', function(cm, vim, helpers) { - cm.setCursor(0, 3); - helpers.doKeys('F', 'x'); - helpers.doKeys(','); - helpers.doKeys('2', ','); - eq(9, cm.getCursor().ch); -}, { value: '01x3xx678x'}); -testVim('t,', function(cm, vim, helpers) { - cm.setCursor(0, 6); - helpers.doKeys('t', 'x'); - helpers.doKeys(','); - helpers.doKeys('2', ','); - eq(3, cm.getCursor().ch); -}, { value: '01x3xx678x'}); -testVim('T,', function(cm, vim, helpers) { - cm.setCursor(0, 4); - helpers.doKeys('T', 'x'); - helpers.doKeys(','); - helpers.doKeys('2', ','); - eq(8, cm.getCursor().ch); -}, { value: '01x3xx67xx'}); -testVim('fd,;', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('f', '4'); - cm.setCursor(0, 0); - helpers.doKeys('d', ';'); - eq('56789', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 9); - helpers.doKeys('d', ','); - eq('01239', cm.getValue()); -}, { value: '0123456789'}); -testVim('Fd,;', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('F', '4'); - cm.setCursor(0, 9); - helpers.doKeys('d', ';'); - eq('01239', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 0); - helpers.doKeys('d', ','); - eq('56789', cm.getValue()); -}, { value: '0123456789'}); -testVim('td,;', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('t', '4'); - cm.setCursor(0, 0); - helpers.doKeys('d', ';'); - eq('456789', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 9); - helpers.doKeys('d', ','); - eq('012349', cm.getValue()); -}, { value: '0123456789'}); -testVim('Td,;', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('T', '4'); - cm.setCursor(0, 9); - helpers.doKeys('d', ';'); - eq('012349', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 0); - helpers.doKeys('d', ','); - eq('456789', cm.getValue()); -}, { value: '0123456789'}); -testVim('fc,;', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('f', '4'); - cm.setCursor(0, 0); - helpers.doKeys('c', ';', ''); - eq('56789', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 9); - helpers.doKeys('c', ','); - eq('01239', cm.getValue()); -}, { value: '0123456789'}); -testVim('Fc,;', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('F', '4'); - cm.setCursor(0, 9); - helpers.doKeys('c', ';', ''); - eq('01239', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 0); - helpers.doKeys('c', ','); - eq('56789', cm.getValue()); -}, { value: '0123456789'}); -testVim('tc,;', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('t', '4'); - cm.setCursor(0, 0); - helpers.doKeys('c', ';', ''); - eq('456789', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 9); - helpers.doKeys('c', ','); - eq('012349', cm.getValue()); -}, { value: '0123456789'}); -testVim('Tc,;', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('T', '4'); - cm.setCursor(0, 9); - helpers.doKeys('c', ';', ''); - eq('012349', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 0); - helpers.doKeys('c', ','); - eq('456789', cm.getValue()); -}, { value: '0123456789'}); -testVim('fy,;', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('f', '4'); - cm.setCursor(0, 0); - helpers.doKeys('y', ';', 'P'); - eq('012340123456789', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 9); - helpers.doKeys('y', ',', 'P'); - eq('012345678456789', cm.getValue()); -}, { value: '0123456789'}); -testVim('Fy,;', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('F', '4'); - cm.setCursor(0, 9); - helpers.doKeys('y', ';', 'p'); - eq('012345678945678', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 0); - helpers.doKeys('y', ',', 'P'); - eq('012340123456789', cm.getValue()); -}, { value: '0123456789'}); -testVim('ty,;', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys('t', '4'); - cm.setCursor(0, 0); - helpers.doKeys('y', ';', 'P'); - eq('01230123456789', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 9); - helpers.doKeys('y', ',', 'p'); - eq('01234567895678', cm.getValue()); -}, { value: '0123456789'}); -testVim('Ty,;', function(cm, vim, helpers) { - cm.setCursor(0, 9); - helpers.doKeys('T', '4'); - cm.setCursor(0, 9); - helpers.doKeys('y', ';', 'p'); - eq('01234567895678', cm.getValue()); - helpers.doKeys('u'); - cm.setCursor(0, 0); - helpers.doKeys('y', ',', 'P'); - eq('01230123456789', cm.getValue()); -}, { value: '0123456789'}); -testVim('HML', function(cm, vim, helpers) { - if (phantom) return; - var lines = 35; - var textHeight = cm.defaultTextHeight(); - cm.setSize(600, lines*textHeight); - cm.setCursor(120, 0); - cm.ace.renderer.scrollCursorIntoView(); cm.refresh(); //ace_patch - helpers.doKeys('H'); - helpers.assertCursorAt(86, 2); - helpers.doKeys('L'); - helpers.assertCursorAt(120, 4); - helpers.doKeys('M'); - helpers.assertCursorAt(103,4); -}, { value: (function(){ - var lines = new Array(100); - var upper = ' xx\n'; - var lower = ' xx\n'; - upper = lines.join(upper); - lower = lines.join(lower); - return upper + lower; -})()}); - -var zVals = []; -forEach(['zb','zz','zt','z-','z.','z'], function(e, idx){ - var lineNum = 250; - var lines = 35; - testVim(e, function(cm, vim, helpers) { - var k1 = e[0]; - var k2 = e.substring(1); - var textHeight = cm.defaultTextHeight(); - cm.setSize(600, lines*textHeight); - cm.setCursor(lineNum, 0); - helpers.doKeys(k1, k2); - zVals[idx] = cm.getScrollInfo().top; - }, { value: (function(){ - return new Array(500).join('\n'); - })()}); -}); -testVim('zb_to_bottom', function(cm, vim, helpers){ - if (isAce) return; - var lineNum = 250; - cm.setSize(600, 35*cm.defaultTextHeight()); - cm.setCursor(lineNum, 0); - cm.ace.renderer.scrollCursorIntoView(); cm.refresh(); - helpers.doKeys('z', 'b'); - var scrollInfo = cm.getScrollInfo(); - eq(scrollInfo.top + scrollInfo.clientHeight, cm.charCoords(Pos(lineNum, 0), 'local').bottom); -}, { value: (function(){ - return new Array(500).join('\n'); -})()}); -testVim('zt_to_top', function(cm, vim, helpers){ - if (isAce) return; - var lineNum = 250; - cm.setSize(600, 35*cm.defaultTextHeight()); - cm.setCursor(lineNum, 0); - helpers.doKeys('z', 't'); - eq(cm.getScrollInfo().top, cm.charCoords(Pos(lineNum, 0), 'local').top); -}, { value: (function(){ - return new Array(500).join('\n'); -})()}); -testVim('zb', function(cm, vim, helpers){ - eq(zVals[2], zVals[5]); -}); - -var moveTillCharacterSandbox = - 'The quick brown fox \n'; -testVim('moveTillCharacter', function(cm, vim, helpers){ - cm.setCursor(0, 0); - // Search for the 'q'. - cm.openDialog = helpers.fakeOpenDialog('q'); - helpers.doKeys('/'); - eq(4, cm.getCursor().ch); - // Jump to just before the first o in the list. - helpers.doKeys('t'); - helpers.doKeys('o'); - eq('The quick brown fox \n', cm.getValue()); - // Delete that one character. - helpers.doKeys('d'); - helpers.doKeys('t'); - helpers.doKeys('o'); - eq('The quick bown fox \n', cm.getValue()); - // Delete everything until the next 'o'. - helpers.doKeys('.'); - eq('The quick box \n', cm.getValue()); - // An unmatched character should have no effect. - helpers.doKeys('d'); - helpers.doKeys('t'); - helpers.doKeys('q'); - eq('The quick box \n', cm.getValue()); - // Matches should only be possible on single lines. - helpers.doKeys('d'); - helpers.doKeys('t'); - helpers.doKeys('z'); - eq('The quick box \n', cm.getValue()); - // After all that, the search for 'q' should still be active, so the 'N' command - // can run it again in reverse. Use that to delete everything back to the 'q'. - helpers.doKeys('d'); - helpers.doKeys('N'); - eq('The ox \n', cm.getValue()); - eq(4, cm.getCursor().ch); -}, { value: moveTillCharacterSandbox}); -testVim('searchForPipe', function(cm, vim, helpers){ - CodeMirror.Vim.setOption('pcre', false); - cm.setCursor(0, 0); - // Search for the '|'. - cm.openDialog = helpers.fakeOpenDialog('|'); - helpers.doKeys('/'); - eq(4, cm.getCursor().ch); -}, { value: 'this|that'}); - - -var 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'; -testVim('scrollMotion', function(cm, vim, helpers){ - if (isAce) return; - var prevCursor, prevScrollInfo; - cm.setCursor(0, 0); - // ctrl-y at the top of the file should have no effect. - helpers.doKeys(''); - eq(0, cm.getCursor().line); - prevScrollInfo = cm.getScrollInfo(); - helpers.doKeys(''); - eq(1, cm.getCursor().line); - is(prevScrollInfo.top < cm.getScrollInfo().top); - // Jump to the end of the sandbox. - cm.setCursor(1000, 0); - cm.refresh(); //ace_patch - prevCursor = cm.getCursor(); - // ctrl-e at the bottom of the file should have no effect. - helpers.doKeys(''); - eq(prevCursor.line, cm.getCursor().line); - cm.refresh(); //ace_patch - prevScrollInfo = cm.getScrollInfo(); - helpers.doKeys(''); - eq(prevCursor.line - 1, cm.getCursor().line, "Y"); - is(prevScrollInfo.top > cm.getScrollInfo().top); -}, { value: scrollMotionSandbox}); - -var squareBracketMotionSandbox = ''+ - '({\n'+//0 - ' ({\n'+//11 - ' /*comment {\n'+//2 - ' */(\n'+//3 - '#else \n'+//4 - ' /* )\n'+//5 - '#if }\n'+//6 - ' )}*/\n'+//7 - ')}\n'+//8 - '{}\n'+//9 - '#else {{\n'+//10 - '{}\n'+//11 - '}\n'+//12 - '{\n'+//13 - '#endif\n'+//14 - '}\n'+//15 - '}\n'+//16 - '#else';//17 -testVim('[[, ]]', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys(']', ']'); - helpers.assertCursorAt(9,0); - helpers.doKeys('2', ']', ']'); - helpers.assertCursorAt(13,0); - helpers.doKeys(']', ']'); - helpers.assertCursorAt(17,0); - helpers.doKeys('[', '['); - helpers.assertCursorAt(13,0); - helpers.doKeys('2', '[', '['); - helpers.assertCursorAt(9,0); - helpers.doKeys('[', '['); - helpers.assertCursorAt(0,0); -}, { value: squareBracketMotionSandbox}); -testVim('[], ][', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doKeys(']', '['); - helpers.assertCursorAt(12,0); - helpers.doKeys('2', ']', '['); - helpers.assertCursorAt(16,0); - helpers.doKeys(']', '['); - helpers.assertCursorAt(17,0); - helpers.doKeys('[', ']'); - helpers.assertCursorAt(16,0); - helpers.doKeys('2', '[', ']'); - helpers.assertCursorAt(12,0); - helpers.doKeys('[', ']'); - helpers.assertCursorAt(0,0); -}, { value: squareBracketMotionSandbox}); -testVim('[{, ]}', function(cm, vim, helpers) { - cm.setCursor(4, 10); - helpers.doKeys('[', '{'); - helpers.assertCursorAt(2,12); - helpers.doKeys('2', '[', '{'); - helpers.assertCursorAt(0,1); - cm.setCursor(4, 10); - helpers.doKeys(']', '}'); - helpers.assertCursorAt(6,11); - helpers.doKeys('2', ']', '}'); - helpers.assertCursorAt(8,1); - cm.setCursor(0,1); - helpers.doKeys(']', '}'); - helpers.assertCursorAt(8,1); - helpers.doKeys('[', '{'); - helpers.assertCursorAt(0,1); -}, { value: squareBracketMotionSandbox}); -testVim('[(, ])', function(cm, vim, helpers) { - cm.setCursor(4, 10); - helpers.doKeys('[', '('); - helpers.assertCursorAt(3,14); - helpers.doKeys('2', '[', '('); - helpers.assertCursorAt(0,0); - cm.setCursor(4, 10); - helpers.doKeys(']', ')'); - helpers.assertCursorAt(5,11); - helpers.doKeys('2', ']', ')'); - helpers.assertCursorAt(8,0); - helpers.doKeys('[', '('); - helpers.assertCursorAt(0,0); - helpers.doKeys(']', ')'); - helpers.assertCursorAt(8,0); -}, { value: squareBracketMotionSandbox}); -testVim('[*, ]*, [/, ]/', function(cm, vim, helpers) { - forEach(['*', '/'], function(key){ - cm.setCursor(7, 0); - helpers.doKeys('2', '[', key); - helpers.assertCursorAt(2,2); - helpers.doKeys('2', ']', key); - helpers.assertCursorAt(7,5); - }); -}, { value: squareBracketMotionSandbox}); -testVim('[#, ]#', function(cm, vim, helpers) { - cm.setCursor(10, 3); - helpers.doKeys('2', '[', '#'); - helpers.assertCursorAt(4,0); - helpers.doKeys('5', ']', '#'); - helpers.assertCursorAt(17,0); - cm.setCursor(10, 3); - helpers.doKeys(']', '#'); - helpers.assertCursorAt(14,0); -}, { value: squareBracketMotionSandbox}); -testVim('[m, ]m, [M, ]M', function(cm, vim, helpers) { - cm.setCursor(11, 0); - helpers.doKeys('[', 'm'); - helpers.assertCursorAt(10,7); - helpers.doKeys('4', '[', 'm'); - helpers.assertCursorAt(1,3); - helpers.doKeys('5', ']', 'm'); - helpers.assertCursorAt(11,0); - helpers.doKeys('[', 'M'); - helpers.assertCursorAt(9,1); - helpers.doKeys('3', ']', 'M'); - helpers.assertCursorAt(15,0); - helpers.doKeys('5', '[', 'M'); - helpers.assertCursorAt(7,3); -}, { value: squareBracketMotionSandbox}); - -testVim('i_indent_right', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedValue = ' word1\nword2\nword3 '; - helpers.doKeys('i', ''); - eq(expectedValue, cm.getValue()); - helpers.assertCursorAt(0, 5); -}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); -testVim('i_indent_left', function(cm, vim, helpers) { - cm.setCursor(0, 3); - var expectedValue = ' word1\nword2\nword3 '; - helpers.doKeys('i', ''); - eq(expectedValue, cm.getValue()); - helpers.assertCursorAt(0, 1); -}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); - -// Ex mode tests -testVim('ex_go_to_line', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doEx('4'); - helpers.assertCursorAt(3, 0); -}, { value: 'a\nb\nc\nd\ne\n'}); -testVim('ex_go_to_mark', function(cm, vim, helpers) { - cm.setCursor(3, 0); - helpers.doKeys('m', 'a'); - cm.setCursor(0, 0); - helpers.doEx('\'a'); - helpers.assertCursorAt(3, 0); -}, { value: 'a\nb\nc\nd\ne\n'}); -testVim('ex_go_to_line_offset', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doEx('+3'); - helpers.assertCursorAt(3, 0); - helpers.doEx('-1'); - helpers.assertCursorAt(2, 0); - helpers.doEx('.2'); - helpers.assertCursorAt(4, 0); - helpers.doEx('.-3'); - helpers.assertCursorAt(1, 0); -}, { value: 'a\nb\nc\nd\ne\n'}); -testVim('ex_go_to_mark_offset', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('m', 'a'); - cm.setCursor(0, 0); - helpers.doEx('\'a1'); - helpers.assertCursorAt(3, 0); - helpers.doEx('\'a-1'); - helpers.assertCursorAt(1, 0); - helpers.doEx('\'a+2'); - helpers.assertCursorAt(4, 0); -}, { value: 'a\nb\nc\nd\ne\n'}); -testVim('ex_write', function(cm, vim, helpers) { - var tmp = CodeMirror.commands.save; - var written; - var actualCm; - CodeMirror.commands.save = function(cm) { - written = true; - actualCm = cm; - }; - // Test that w, wr, wri ... write all trigger :write. - var command = 'write'; - for (var i = 1; i < command.length; i++) { - written = false; - actualCm = null; - helpers.doEx(command.substring(0, i)); - eq(written, true); - eq(actualCm, cm); - } - CodeMirror.commands.save = tmp; -}); -testVim('ex_sort', function(cm, vim, helpers) { - helpers.doEx('sort'); - eq('Z\na\nb\nc\nd', cm.getValue()); -}, { value: 'b\nZ\nd\nc\na'}); -testVim('ex_sort_reverse', function(cm, vim, helpers) { - helpers.doEx('sort!'); - eq('d\nc\nb\na', cm.getValue()); -}, { value: 'b\nd\nc\na'}); -testVim('ex_sort_range', function(cm, vim, helpers) { - helpers.doEx('2,3sort'); - eq('b\nc\nd\na', cm.getValue()); -}, { value: 'b\nd\nc\na'}); -testVim('ex_sort_oneline', function(cm, vim, helpers) { - helpers.doEx('2sort'); - // Expect no change. - eq('b\nd\nc\na', cm.getValue()); -}, { value: 'b\nd\nc\na'}); -testVim('ex_sort_ignoreCase', function(cm, vim, helpers) { - helpers.doEx('sort i'); - eq('a\nb\nc\nd\nZ', cm.getValue()); -}, { value: 'b\nZ\nd\nc\na'}); -testVim('ex_sort_unique', function(cm, vim, helpers) { - helpers.doEx('sort u'); - eq('Z\na\nb\nc\nd', cm.getValue()); -}, { value: 'b\nZ\na\na\nd\na\nc\na'}); -testVim('ex_sort_decimal', function(cm, vim, helpers) { - helpers.doEx('sort d'); - eq('d3\n s5\n6\n.9', cm.getValue()); -}, { value: '6\nd3\n s5\n.9'}); -testVim('ex_sort_decimal_negative', function(cm, vim, helpers) { - helpers.doEx('sort d'); - eq('z-9\nd3\n s5\n6\n.9', cm.getValue()); -}, { value: '6\nd3\n s5\n.9\nz-9'}); -testVim('ex_sort_decimal_reverse', function(cm, vim, helpers) { - helpers.doEx('sort! d'); - eq('.9\n6\n s5\nd3', cm.getValue()); -}, { value: '6\nd3\n s5\n.9'}); -testVim('ex_sort_hex', function(cm, vim, helpers) { - helpers.doEx('sort x'); - eq(' s5\n6\n.9\n&0xB\nd3', cm.getValue()); -}, { value: '6\nd3\n s5\n&0xB\n.9'}); -testVim('ex_sort_octal', function(cm, vim, helpers) { - helpers.doEx('sort o'); - eq('.9\n.8\nd3\n s5\n6', cm.getValue()); -}, { value: '6\nd3\n s5\n.9\n.8'}); -testVim('ex_sort_decimal_mixed', function(cm, vim, helpers) { - helpers.doEx('sort d'); - eq('z\ny\nc1\nb2\na3', cm.getValue()); -}, { value: 'a3\nz\nc1\ny\nb2'}); -testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) { - helpers.doEx('sort! d'); - eq('a3\nb2\nc1\nz\ny', cm.getValue()); -}, { value: 'a3\nz\nc1\ny\nb2'}); -testVim('ex_sort_pattern_alpha', function(cm, vim, helpers) { - helpers.doEx('sort /[a-z]/'); - eq('a3\nb2\nc1\ny\nz', cm.getValue()); -}, { value: 'z\ny\nc1\nb2\na3'}); -testVim('ex_sort_pattern_alpha_reverse', function(cm, vim, helpers) { - helpers.doEx('sort! /[a-z]/'); - eq('z\ny\nc1\nb2\na3', cm.getValue()); -}, { value: 'z\ny\nc1\nb2\na3'}); -testVim('ex_sort_pattern_alpha_ignoreCase', function(cm, vim, helpers) { - helpers.doEx('sort i/[a-z]/'); - eq('a3\nb2\nC1\nY\nz', cm.getValue()); -}, { value: 'z\nY\nC1\nb2\na3'}); -testVim('ex_sort_pattern_alpha_longer', function(cm, vim, helpers) { - helpers.doEx('sort /[a-z]+/'); - eq('a\naa\nab\nade\nadele\nadelle\nadriana\nalex\nalexandra\nb\nc\ny\nz', cm.getValue()); -}, { value: 'z\nab\naa\nade\nadelle\nalexandra\nalex\nadriana\nadele\ny\nc\nb\na'}); -testVim('ex_sort_pattern_alpha_only', function(cm, vim, helpers) { - helpers.doEx('sort /^[a-z]$/'); - eq('z1\ny2\na3\nb\nc', cm.getValue()); -}, { value: 'z1\ny2\na3\nc\nb'}); -testVim('ex_sort_pattern_alpha_only_reverse', function(cm, vim, helpers) { - helpers.doEx('sort! /^[a-z]$/'); - eq('c\nb\nz1\ny2\na3', cm.getValue()); -}, { value: 'z1\ny2\na3\nc\nb'}); -testVim('ex_sort_pattern_alpha_num', function(cm, vim, helpers) { - helpers.doEx('sort /[a-z][0-9]/'); - eq('c\nb\na3\ny2\nz1', cm.getValue()); -}, { value: 'z1\ny2\na3\nc\nb'}); -// test for :global command -testVim('ex_global', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doEx('g/one/s//two'); - eq('two two\n two two\n two two', cm.getValue()); - helpers.doEx('1,2g/two/s//one'); - eq('one one\n one one\n two two', cm.getValue()); -}, {value: 'one one\n one one\n one one'}); -testVim('ex_global_confirm', function(cm, vim, helpers) { - cm.setCursor(0, 0); - var onKeyDown; - var openDialogSave = cm.openDialog; - var KEYCODES = { - a: 65, - n: 78, - q: 81, - y: 89 - }; - // Intercept the ex command, 'global' - cm.openDialog = function(template, callback, options) { - // Intercept the prompt for the embedded ex command, 'substitute' - cm.openDialog = function(template, callback, options) { - onKeyDown = options.onKeyDown; - }; - callback('g/one/s//two/gc'); - }; - helpers.doKeys(':'); - var close = function() {}; - onKeyDown({keyCode: KEYCODES.n}, '', close); - onKeyDown({keyCode: KEYCODES.y}, '', close); - onKeyDown({keyCode: KEYCODES.a}, '', close); - onKeyDown({keyCode: KEYCODES.q}, '', close); - onKeyDown({keyCode: KEYCODES.y}, '', close); - eq('one two\n two two\n one one\n two one\n one one', cm.getValue()); -}, {value: 'one one\n one one\n one one\n one one\n one one'}); -// Basic substitute tests. -testVim('ex_substitute_same_line', function(cm, vim, helpers) { - cm.setCursor(1, 0); - helpers.doEx('s/one/two/g'); - eq('one one\n two two', cm.getValue()); -}, { value: 'one one\n one one'}); -testVim('ex_substitute_alternate_separator', function(cm, vim, helpers) { - cm.setCursor(1, 0); - helpers.doEx('s#o/e#two#g'); - eq('o/e o/e\n two two', cm.getValue()); -}, { value: 'o/e o/e\n o/e o/e'}); -testVim('ex_substitute_full_file', function(cm, vim, helpers) { - cm.setCursor(1, 0); - helpers.doEx('%s/one/two/g'); - eq('two two\n two two', cm.getValue()); -}, { value: 'one one\n one one'}); -testVim('ex_substitute_input_range', function(cm, vim, helpers) { - cm.setCursor(1, 0); - helpers.doEx('1,3s/\\d/0/g'); - eq('0\n0\n0\n4', cm.getValue()); -}, { value: '1\n2\n3\n4' }); -testVim('ex_substitute_range_current_to_input', function(cm, vim, helpers) { - cm.setCursor(1, 0); - helpers.doEx('.,3s/\\d/0/g'); - eq('1\n0\n0\n4', cm.getValue()); -}, { value: '1\n2\n3\n4' }); -testVim('ex_substitute_range_input_to_current', function(cm, vim, helpers) { - cm.setCursor(3, 0); - helpers.doEx('2,.s/\\d/0/g'); - eq('1\n0\n0\n0\n5', cm.getValue()); -}, { value: '1\n2\n3\n4\n5' }); -testVim('ex_substitute_range_offset', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doEx('-1,+1s/\\d/0/g'); - eq('1\n0\n0\n0\n5', cm.getValue()); -}, { value: '1\n2\n3\n4\n5' }); -testVim('ex_substitute_range_implicit_offset', function(cm, vim, helpers) { - cm.setCursor(0, 0); - helpers.doEx('.1,.3s/\\d/0/g'); - eq('1\n0\n0\n0\n5', cm.getValue()); -}, { value: '1\n2\n3\n4\n5' }); -testVim('ex_substitute_to_eof', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doEx('.,$s/\\d/0/g'); - eq('1\n2\n0\n0\n0', cm.getValue()); -}, { value: '1\n2\n3\n4\n5' }); -testVim('ex_substitute_to_relative_eof', function(cm, vim, helpers) { - cm.setCursor(4, 0); - helpers.doEx('2,$-2s/\\d/0/g'); - eq('1\n0\n0\n4\n5', cm.getValue()); -}, { value: '1\n2\n3\n4\n5' }); -testVim('ex_substitute_range_mark', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('ma'); - cm.setCursor(0, 0); - helpers.doEx('.,\'as/\\d/0/g'); - eq('0\n0\n0\n4\n5', cm.getValue()); -}, { value: '1\n2\n3\n4\n5' }); -testVim('ex_substitute_range_mark_offset', function(cm, vim, helpers) { - cm.setCursor(2, 0); - helpers.doKeys('ma'); - cm.setCursor(0, 0); - helpers.doEx('\'a-1,\'a+1s/\\d/0/g'); - eq('1\n0\n0\n0\n5', cm.getValue()); -}, { value: '1\n2\n3\n4\n5' }); -testVim('ex_substitute_visual_range', function(cm, vim, helpers) { - cm.setCursor(1, 0); - // Set last visual mode selection marks '< and '> at lines 2 and 4 - helpers.doKeys('V', '2', 'j', 'v'); - helpers.doEx('\'<,\'>s/\\d/0/g'); - eq('1\n0\n0\n0\n5', cm.getValue()); -}, { value: '1\n2\n3\n4\n5' }); -testVim('ex_substitute_empty_query', function(cm, vim, helpers) { - // If the query is empty, use last query. - cm.setCursor(1, 0); - cm.openDialog = helpers.fakeOpenDialog('1'); - helpers.doKeys('/'); - helpers.doEx('s//b/g'); - eq('abb ab2 ab3', cm.getValue()); -}, { value: 'a11 a12 a13' }); -testVim('ex_substitute_javascript', function(cm, vim, helpers) { - CodeMirror.Vim.setOption('pcre', false); - cm.setCursor(1, 0); - // Throw all the things that javascript likes to treat as special values - // into the replace part. All should be literal (this is VIM). - helpers.doEx('s/\\(\\d+\\)/$$ $\' $` $& \\1/g') - eq('a $$ $\' $` $& 0 b', cm.getValue()); -}, { value: 'a 0 b' }); -testVim('ex_substitute_empty_arguments', function(cm,vim,helpers) { - cm.setCursor(0, 0); - helpers.doEx('s/a/b/g'); - cm.setCursor(1, 0); - helpers.doEx('s'); - eq('b b\nb a', cm.getValue()); -}, {value: 'a a\na a'}); - -// More complex substitute tests that test both pcre and nopcre options. -function testSubstitute(name, options) { - testVim(name + '_pcre', function(cm, vim, helpers) { - cm.setCursor(1, 0); - CodeMirror.Vim.setOption('pcre', true); - helpers.doEx(options.expr); - eq(options.expectedValue, cm.getValue()); - }, options); - // If no noPcreExpr is defined, assume that it's the same as the expr. - var noPcreExpr = options.noPcreExpr ? options.noPcreExpr : options.expr; - testVim(name + '_nopcre', function(cm, vim, helpers) { - cm.setCursor(1, 0); - CodeMirror.Vim.setOption('pcre', false); - helpers.doEx(noPcreExpr); - eq(options.expectedValue, cm.getValue()); - }, options); -} -testSubstitute('ex_substitute_capture', { - value: 'a11 a12 a13', - expectedValue: 'a1111 a1212 a1313', - // $n is a backreference - expr: 's/(\\d+)/$1$1/g', - // \n is a backreference. - noPcreExpr: 's/\\(\\d+\\)/\\1\\1/g'}); -testSubstitute('ex_substitute_capture2', { - value: 'a 0 b', - expectedValue: 'a $00 b', - expr: 's/(\\d+)/$$$1$1/g', - noPcreExpr: 's/\\(\\d+\\)/$\\1\\1/g'}); -testSubstitute('ex_substitute_nocapture', { - value: 'a11 a12 a13', - expectedValue: 'a$1$1 a$1$1 a$1$1', - expr: 's/(\\d+)/$$1$$1/g', - noPcreExpr: 's/\\(\\d+\\)/$1$1/g'}); -testSubstitute('ex_substitute_nocapture2', { - value: 'a 0 b', - expectedValue: 'a $10 b', - expr: 's/(\\d+)/$$1$1/g', - noPcreExpr: 's/\\(\\d+\\)/\\$1\\1/g'}); -testSubstitute('ex_substitute_nocapture', { - value: 'a b c', - expectedValue: 'a $ c', - expr: 's/b/$$/', - noPcreExpr: 's/b/$/'}); -testSubstitute('ex_substitute_slash_regex', { - value: 'one/two \n three/four', - expectedValue: 'one|two \n three|four', - expr: '%s/\\//|'}); -testSubstitute('ex_substitute_pipe_regex', { - value: 'one|two \n three|four', - expectedValue: 'one,two \n three,four', - expr: '%s/\\|/,/', - noPcreExpr: '%s/|/,/'}); -testSubstitute('ex_substitute_or_regex', { - value: 'one|two \n three|four', - expectedValue: 'ana|twa \n thraa|faar', - expr: '%s/o|e|u/a/g', - noPcreExpr: '%s/o\\|e\\|u/a/g'}); -testSubstitute('ex_substitute_or_word_regex', { - value: 'one|two \n three|four', - expectedValue: 'five|five \n three|four', - expr: '%s/(one|two)/five/g', - noPcreExpr: '%s/\\(one\\|two\\)/five/g'}); -testSubstitute('ex_substitute_backslashslash_regex', { - value: 'one\\two \n three\\four', - expectedValue: 'one,two \n three,four', - expr: '%s/\\\\/,'}); -testSubstitute('ex_substitute_slash_replacement', { - value: 'one,two \n three,four', - expectedValue: 'one/two \n three/four', - expr: '%s/,/\\/'}); -testSubstitute('ex_substitute_backslash_replacement', { - value: 'one,two \n three,four', - expectedValue: 'one\\two \n three\\four', - expr: '%s/,/\\\\/g'}); -testSubstitute('ex_substitute_multibackslash_replacement', { - value: 'one,two \n three,four', - expectedValue: 'one\\\\\\\\two \n three\\\\\\\\four', // 2*8 backslashes. - expr: '%s/,/\\\\\\\\\\\\\\\\/g'}); // 16 backslashes. -isAce || testSubstitute('ex_substitute_dollar_match', { - value: 'one,two \n three,four', - expectedValue: 'one,two ,\n three,four', - expr: '%s/$/,/g'}); -isAce || testSubstitute('ex_substitute_newline_match', { - value: 'one,two \n three,four', - expectedValue: 'one,two , three,four', - expr: '%s/\\n/,/g'}); -testSubstitute('ex_substitute_newline_replacement', { - value: 'one,two \n three,four', - expectedValue: 'one\ntwo \n three\nfour', - expr: '%s/,/\\n/g'}); -testSubstitute('ex_substitute_braces_word', { - value: 'ababab abb ab{2}', - expectedValue: 'ab abb ab{2}', - expr: '%s/(ab){2}//g', - noPcreExpr: '%s/\\(ab\\)\\{2\\}//g'}); -testSubstitute('ex_substitute_braces_range', { - value: 'a aa aaa aaaa', - expectedValue: 'a a', - expr: '%s/a{2,3}//g', - noPcreExpr: '%s/a\\{2,3\\}//g'}); -testSubstitute('ex_substitute_braces_literal', { - value: 'ababab abb ab{2}', - expectedValue: 'ababab abb ', - expr: '%s/ab\\{2\\}//g', - noPcreExpr: '%s/ab{2}//g'}); -testSubstitute('ex_substitute_braces_char', { - value: 'ababab abb ab{2}', - expectedValue: 'ababab ab{2}', - expr: '%s/ab{2}//g', - noPcreExpr: '%s/ab\\{2\\}//g'}); -testSubstitute('ex_substitute_braces_no_escape', { - value: 'ababab abb ab{2}', - expectedValue: 'ababab ab{2}', - expr: '%s/ab{2}//g', - noPcreExpr: '%s/ab\\{2}//g'}); -testSubstitute('ex_substitute_count', { - value: '1\n2\n3\n4', - expectedValue: '1\n0\n0\n4', - expr: 's/\\d/0/i 2'}); -testSubstitute('ex_substitute_count_with_range', { - value: '1\n2\n3\n4', - expectedValue: '1\n2\n0\n0', - expr: '1,3s/\\d/0/ 3'}); -testSubstitute('ex_substitute_not_global', { - value: 'aaa\nbaa\ncaa', - expectedValue: 'xaa\nbxa\ncxa', - expr: '%s/a/x/'}); -function testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) { - testVim(name, function(cm, vim, helpers) { - var savedOpenDialog = cm.openDialog; - var savedKeyName = CodeMirror.keyName; - var onKeyDown; - var recordedCallback; - var closed = true; // Start out closed, set false on second openDialog. - function close() { - closed = true; - } - // First openDialog should save callback. - cm.openDialog = function(template, callback, options) { - recordedCallback = callback; - } - // Do first openDialog. - helpers.doKeys(':'); - // Second openDialog should save keyDown handler. - cm.openDialog = function(template, callback, options) { - onKeyDown = options.onKeyDown; - closed = false; - }; - // Return the command to Vim and trigger second openDialog. - recordedCallback(command); - // The event should really use keyCode, but here just mock it out and use - // key and replace keyName to just return key. - CodeMirror.keyName = function (e) { return e.key; } - keys = keys.toUpperCase(); - for (var i = 0; i < keys.length; i++) { - is(!closed); - onKeyDown({ key: keys.charAt(i) }, '', close); - } - try { - eq(expectedValue, cm.getValue()); - helpers.assertCursorAt(finalPos); - is(closed); - } catch(e) { - throw e - } finally { - // Restore overridden functions. - CodeMirror.keyName = savedKeyName; - cm.openDialog = savedOpenDialog; - } - }, { value: initialValue }); -} -testSubstituteConfirm('ex_substitute_confirm_emptydoc', - '%s/x/b/c', '', '', '', makeCursor(0, 0)); -testSubstituteConfirm('ex_substitute_confirm_nomatch', - '%s/x/b/c', 'ba a\nbab', 'ba a\nbab', '', makeCursor(0, 0)); -testSubstituteConfirm('ex_substitute_confirm_accept', - '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'yyy', makeCursor(1, 1)); -testSubstituteConfirm('ex_substitute_confirm_random_keys', - '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'ysdkywerty', makeCursor(1, 1)); -testSubstituteConfirm('ex_substitute_confirm_some', - '%s/a/b/cg', 'ba a\nbab', 'bb a\nbbb', 'yny', makeCursor(1, 1)); -testSubstituteConfirm('ex_substitute_confirm_all', - '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'a', makeCursor(1, 1)); -testSubstituteConfirm('ex_substitute_confirm_accept_then_all', - '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'ya', makeCursor(1, 1)); -testSubstituteConfirm('ex_substitute_confirm_quit', - '%s/a/b/cg', 'ba a\nbab', 'bb a\nbab', 'yq', makeCursor(0, 3)); -testSubstituteConfirm('ex_substitute_confirm_last', - '%s/a/b/cg', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3)); -testSubstituteConfirm('ex_substitute_confirm_oneline', - '1s/a/b/cg', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3)); -testSubstituteConfirm('ex_substitute_confirm_range_accept', - '1,2s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyy', makeCursor(1, 0)); -testSubstituteConfirm('ex_substitute_confirm_range_some', - '1,3s/a/b/cg', 'aa\na \na\na', 'ba\nb \nb\na', 'ynyy', makeCursor(2, 0)); -testSubstituteConfirm('ex_substitute_confirm_range_all', - '1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \nb\na', 'a', makeCursor(2, 0)); -testSubstituteConfirm('ex_substitute_confirm_range_last', - '1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyl', makeCursor(1, 0)); -//:noh should clear highlighting of search-results but allow to resume search through n -testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) { - cm.openDialog = helpers.fakeOpenDialog('match'); - helpers.doKeys('?'); - helpers.doEx('noh'); - eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\'t cleared'); - helpers.doKeys('n'); - helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting'); -}, { value: 'match nope match \n nope Match' }); -testVim('ex_yank', function (cm, vim, helpers) { - var curStart = makeCursor(3, 0); - cm.setCursor(curStart); - helpers.doEx('y'); - var register = helpers.getRegisterController().getRegister(); - var line = cm.getLine(3); - eq(line + '\n', register.toString()); -}); -testVim('set_boolean', function(cm, vim, helpers) { - CodeMirror.Vim.defineOption('testoption', true, 'boolean'); - // Test default value is set. - is(CodeMirror.Vim.getOption('testoption')); - expectFail(function() { - // Test fail to set to non-boolean - CodeMirror.Vim.setOption('testoption', '5'); - }, isAce); - // Test setOption - CodeMirror.Vim.setOption('testoption', false); - is(!CodeMirror.Vim.getOption('testoption')); -}); -testVim('ex_set_boolean', function(cm, vim, helpers) { - CodeMirror.Vim.defineOption('testoption', true, 'boolean'); - // Test default value is set. - is(CodeMirror.Vim.getOption('testoption')); - expectFail(function() { - // Test fail to set to non-boolean - helpers.doEx('set testoption=22'); - }, isAce); - // Test setOption - helpers.doEx('set notestoption'); - is(!CodeMirror.Vim.getOption('testoption')); -}); -testVim('set_string', function(cm, vim, helpers) { - CodeMirror.Vim.defineOption('testoption', 'a', 'string'); - // Test default value is set. - eq('a', CodeMirror.Vim.getOption('testoption')); - isAce || expectFail(function() { - // Test fail to set non-string. - CodeMirror.Vim.setOption('testoption', true); - }); - isAce || expectFail(function() { - // Test fail to set 'notestoption' - CodeMirror.Vim.setOption('notestoption', 'b'); - }); - // Test setOption - CodeMirror.Vim.setOption('testoption', 'c'); - eq('c', CodeMirror.Vim.getOption('testoption')); -}); -testVim('ex_set_string', function(cm, vim, helpers) { - CodeMirror.Vim.defineOption('testopt', 'a', 'string'); - // Test default value is set. - eq('a', CodeMirror.Vim.getOption('testopt')); - isAce || expectFail(function() { - // Test fail to set 'notestopt' - helpers.doEx('set notestopt=b'); - }); - // Test setOption - helpers.doEx('set testopt=c') - eq('c', CodeMirror.Vim.getOption('testopt')); - helpers.doEx('set testopt=c') - eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global - eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local - eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global - eq('c', CodeMirror.Vim.getOption('testopt')); // global - // Test setOption global - helpers.doEx('setg testopt=d') - eq('c', CodeMirror.Vim.getOption('testopt', cm)); - eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); - eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); - eq('d', CodeMirror.Vim.getOption('testopt')); - // Test setOption local - helpers.doEx('setl testopt=e') - eq('e', CodeMirror.Vim.getOption('testopt', cm)); - eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); - eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); - eq('d', CodeMirror.Vim.getOption('testopt')); -}); -testVim('ex_set_callback', function(cm, vim, helpers) { - var global; - - function cb(val, cm, cfg) { - if (val === undefined) { - // Getter - if (cm) { - return cm._local; - } else { - return global; - } - } else { - // Setter - if (cm) { - cm._local = val; - } else { - global = val; - } - } - } - - CodeMirror.Vim.defineOption('testopt', 'a', 'string', cb); - // Test default value is set. - eq('a', CodeMirror.Vim.getOption('testopt')); - expectFail(function() { - // Test fail to set 'notestopt' - helpers.doEx('set notestopt=b'); - }, isAce); - // Test setOption (Identical to the string tests, but via callback instead) - helpers.doEx('set testopt=c') - eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global - eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local - eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global - eq('c', CodeMirror.Vim.getOption('testopt')); // global - // Test setOption global - helpers.doEx('setg testopt=d') - eq('c', CodeMirror.Vim.getOption('testopt', cm)); - eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); - eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); - eq('d', CodeMirror.Vim.getOption('testopt')); - // Test setOption local - helpers.doEx('setl testopt=e') - eq('e', CodeMirror.Vim.getOption('testopt', cm)); - eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); - eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); - eq('d', CodeMirror.Vim.getOption('testopt')); -}) -testVim('ex_set_filetype', function(cm, vim, helpers) { - CodeMirror.defineMode('test_mode', function() { - return {token: function(stream) { - stream.match(/^\s+|^\S+/); - }}; - }); - CodeMirror.defineMode('test_mode_2', function() { - return {token: function(stream) { - stream.match(/^\s+|^\S+/); - }}; - }); - // Test mode is set. - helpers.doEx('set filetype=test_mode'); - eq('test_mode', cm.getMode().name); - // Test 'ft' alias also sets mode. - helpers.doEx('set ft=test_mode_2'); - eq('test_mode_2', cm.getMode().name); -}); -testVim('ex_set_filetype_null', function(cm, vim, helpers) { - CodeMirror.defineMode('test_mode', function() { - return {token: function(stream) { - stream.match(/^\s+|^\S+/); - }}; - }); - cm.setOption('mode', 'test_mode'); - // Test mode is set to null. - helpers.doEx('set filetype='); - eq('null', cm.getMode().name); -}); -// TODO: Reset key maps after each test. -testVim('ex_map_key2key', function(cm, vim, helpers) { - helpers.doEx('map a x'); - helpers.doKeys('a'); - helpers.assertCursorAt(0, 0); - eq('bc', cm.getValue()); -}, { value: 'abc' }); -testVim('ex_unmap_key2key', function(cm, vim, helpers) { - helpers.doEx('unmap a'); - helpers.doKeys('a'); - eq('vim-insert', cm.getOption('keyMap')); -}, { value: 'abc' }); -testVim('ex_unmap_key2key_does_not_remove_default', function(cm, vim, helpers) { - if (isAce) return; - expectFail(function() { - helpers.doEx('unmap a'); - }); - helpers.doKeys('a'); - eq('vim-insert', cm.getOption('keyMap')); -}, { value: 'abc' }); -testVim('ex_map_key2key_to_colon', function(cm, vim, helpers) { - helpers.doEx('map ; :'); - var dialogOpened = false; - cm.openDialog = function() { - dialogOpened = true; - } - helpers.doKeys(';'); - eq(dialogOpened, true); -}); -testVim('ex_map_ex2key:', function(cm, vim, helpers) { - helpers.doEx('map :del x'); - helpers.doEx('del'); - helpers.assertCursorAt(0, 0); - eq('bc', cm.getValue()); -}, { value: 'abc' }); -testVim('ex_map_ex2ex', function(cm, vim, helpers) { - helpers.doEx('map :del :w'); - var tmp = CodeMirror.commands.save; - var written = false; - var actualCm; - CodeMirror.commands.save = function(cm) { - written = true; - actualCm = cm; - }; - helpers.doEx('del'); - CodeMirror.commands.save = tmp; - eq(written, true); - eq(actualCm, cm); -}); -testVim('ex_map_key2ex', function(cm, vim, helpers) { - helpers.doEx('map a :w'); - var tmp = CodeMirror.commands.save; - var written = false; - var actualCm; - CodeMirror.commands.save = function(cm) { - written = true; - actualCm = cm; - }; - helpers.doKeys('a'); - CodeMirror.commands.save = tmp; - eq(written, true); - eq(actualCm, cm); -}); -testVim('ex_map_key2key_visual_api', function(cm, vim, helpers) { - CodeMirror.Vim.map('b', ':w', 'visual'); - var tmp = CodeMirror.commands.save; - var written = false; - var actualCm; - CodeMirror.commands.save = function(cm) { - written = true; - actualCm = cm; - }; - // Mapping should not work in normal mode. - helpers.doKeys('b'); - eq(written, false); - // Mapping should work in visual mode. - helpers.doKeys('v', 'b'); - eq(written, true); - eq(actualCm, cm); - - CodeMirror.commands.save = tmp; -}); -testVim('ex_imap', function(cm, vim, helpers) { - CodeMirror.Vim.map('jk', '', 'insert'); - helpers.doKeys('i'); - is(vim.insertMode); - helpers.doKeys('j', 'k'); - is(!vim.insertMode); - cm.setCursor(0, 1); - CodeMirror.Vim.map('jj', '', 'insert'); - helpers.doKeys('', '2', 'j', 'l', 'c'); - var replacement = fillArray('fo', 3); - cm.replaceSelections(replacement); - eq('1fo4\n5fo8\nafodefg', cm.getValue()); - helpers.doKeys('j', 'j'); - cm.setCursor(0, 0); - helpers.doKeys('.'); - eq('foo4\nfoo8\nfoodefg', cm.getValue()); -}, { value: '1234\n5678\nabcdefg' }); -testVim('ex_unmap_api', function(cm, vim, helpers) { - CodeMirror.Vim.map('', 'gg', 'normal'); - is(CodeMirror.Vim.handleKey(cm, "", "normal"), "Alt-X key is mapped"); - CodeMirror.Vim.unmap("", "normal"); - is(!CodeMirror.Vim.handleKey(cm, "", "normal"), "Alt-X key is unmapped"); -}); - -// Testing registration of functions as ex-commands and mapping to -keys -testVim('ex_api_test', function(cm, vim, helpers) { - var res=false; - var val='from'; - CodeMirror.Vim.defineEx('extest','ext',function(cm,params){ - if(params.args)val=params.args[0]; - else res=true; - }); - helpers.doEx(':ext to'); - eq(val,'to','Defining ex-command failed'); - CodeMirror.Vim.map('',':ext'); - helpers.doKeys('',''); - is(res,'Mapping to key failed'); -}); -// For now, this test needs to be last because it messes up : for future tests. -testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) { - helpers.doEx('map : x'); - helpers.doKeys(':'); - helpers.assertCursorAt(0, 0); - eq('bc', cm.getValue()); -}, { value: 'abc' }); - -// Test event handlers -testVim('beforeSelectionChange', function(cm, vim, helpers) { - cm.setCursor(0, 100); - eqCursorPos(cm.getCursor('head'), cm.getCursor('anchor')); -}, { value: 'abc' }); - -testVim('increment_binary', function(cm, vim, helpers) { - cm.setCursor(0, 4); - helpers.doKeys(''); - eq('0b001', cm.getValue()); - helpers.doKeys(''); - eq('0b010', cm.getValue()); - helpers.doKeys(''); - eq('0b001', cm.getValue()); - helpers.doKeys(''); - eq('0b000', cm.getValue()); - cm.setCursor(0, 0); - helpers.doKeys(''); - eq('0b001', cm.getValue()); - helpers.doKeys(''); - eq('0b010', cm.getValue()); - helpers.doKeys(''); - eq('0b001', cm.getValue()); - helpers.doKeys(''); - eq('0b000', cm.getValue()); -}, { value: '0b000' }); - -testVim('increment_octal', function(cm, vim, helpers) { - cm.setCursor(0, 2); - helpers.doKeys(''); - eq('001', cm.getValue()); - helpers.doKeys(''); - eq('002', cm.getValue()); - helpers.doKeys(''); - eq('003', cm.getValue()); - helpers.doKeys(''); - eq('004', cm.getValue()); - helpers.doKeys(''); - eq('005', cm.getValue()); - helpers.doKeys(''); - eq('006', cm.getValue()); - helpers.doKeys(''); - eq('007', cm.getValue()); - helpers.doKeys(''); - eq('010', cm.getValue()); - helpers.doKeys(''); - eq('007', cm.getValue()); - helpers.doKeys(''); - eq('006', cm.getValue()); - helpers.doKeys(''); - eq('005', cm.getValue()); - helpers.doKeys(''); - eq('004', cm.getValue()); - helpers.doKeys(''); - eq('003', cm.getValue()); - helpers.doKeys(''); - eq('002', cm.getValue()); - helpers.doKeys(''); - eq('001', cm.getValue()); - helpers.doKeys(''); - eq('000', cm.getValue()); - cm.setCursor(0, 0); - helpers.doKeys(''); - eq('001', cm.getValue()); - helpers.doKeys(''); - eq('002', cm.getValue()); - helpers.doKeys(''); - eq('001', cm.getValue()); - helpers.doKeys(''); - eq('000', cm.getValue()); -}, { value: '000' }); - -testVim('increment_decimal', function(cm, vim, helpers) { - cm.setCursor(0, 2); - helpers.doKeys(''); - eq('101', cm.getValue()); - helpers.doKeys(''); - eq('102', cm.getValue()); - helpers.doKeys(''); - eq('103', cm.getValue()); - helpers.doKeys(''); - eq('104', cm.getValue()); - helpers.doKeys(''); - eq('105', cm.getValue()); - helpers.doKeys(''); - eq('106', cm.getValue()); - helpers.doKeys(''); - eq('107', cm.getValue()); - helpers.doKeys(''); - eq('108', cm.getValue()); - helpers.doKeys(''); - eq('109', cm.getValue()); - helpers.doKeys(''); - eq('110', cm.getValue()); - helpers.doKeys(''); - eq('109', cm.getValue()); - helpers.doKeys(''); - eq('108', cm.getValue()); - helpers.doKeys(''); - eq('107', cm.getValue()); - helpers.doKeys(''); - eq('106', cm.getValue()); - helpers.doKeys(''); - eq('105', cm.getValue()); - helpers.doKeys(''); - eq('104', cm.getValue()); - helpers.doKeys(''); - eq('103', cm.getValue()); - helpers.doKeys(''); - eq('102', cm.getValue()); - helpers.doKeys(''); - eq('101', cm.getValue()); - helpers.doKeys(''); - eq('100', cm.getValue()); - cm.setCursor(0, 0); - helpers.doKeys(''); - eq('101', cm.getValue()); - helpers.doKeys(''); - eq('102', cm.getValue()); - helpers.doKeys(''); - eq('101', cm.getValue()); - helpers.doKeys(''); - eq('100', cm.getValue()); -}, { value: '100' }); - -testVim('increment_decimal_single_zero', function(cm, vim, helpers) { - helpers.doKeys(''); - eq('1', cm.getValue()); - helpers.doKeys(''); - eq('2', cm.getValue()); - helpers.doKeys(''); - eq('3', cm.getValue()); - helpers.doKeys(''); - eq('4', cm.getValue()); - helpers.doKeys(''); - eq('5', cm.getValue()); - helpers.doKeys(''); - eq('6', cm.getValue()); - helpers.doKeys(''); - eq('7', cm.getValue()); - helpers.doKeys(''); - eq('8', cm.getValue()); - helpers.doKeys(''); - eq('9', cm.getValue()); - helpers.doKeys(''); - eq('10', cm.getValue()); - helpers.doKeys(''); - eq('9', cm.getValue()); - helpers.doKeys(''); - eq('8', cm.getValue()); - helpers.doKeys(''); - eq('7', cm.getValue()); - helpers.doKeys(''); - eq('6', cm.getValue()); - helpers.doKeys(''); - eq('5', cm.getValue()); - helpers.doKeys(''); - eq('4', cm.getValue()); - helpers.doKeys(''); - eq('3', cm.getValue()); - helpers.doKeys(''); - eq('2', cm.getValue()); - helpers.doKeys(''); - eq('1', cm.getValue()); - helpers.doKeys(''); - eq('0', cm.getValue()); - cm.setCursor(0, 0); - helpers.doKeys(''); - eq('1', cm.getValue()); - helpers.doKeys(''); - eq('2', cm.getValue()); - helpers.doKeys(''); - eq('1', cm.getValue()); - helpers.doKeys(''); - eq('0', cm.getValue()); -}, { value: '0' }); - -testVim('increment_hexadecimal', function(cm, vim, helpers) { - cm.setCursor(0, 2); - helpers.doKeys(''); - eq('0x1', cm.getValue()); - helpers.doKeys(''); - eq('0x2', cm.getValue()); - helpers.doKeys(''); - eq('0x3', cm.getValue()); - helpers.doKeys(''); - eq('0x4', cm.getValue()); - helpers.doKeys(''); - eq('0x5', cm.getValue()); - helpers.doKeys(''); - eq('0x6', cm.getValue()); - helpers.doKeys(''); - eq('0x7', cm.getValue()); - helpers.doKeys(''); - eq('0x8', cm.getValue()); - helpers.doKeys(''); - eq('0x9', cm.getValue()); - helpers.doKeys(''); - eq('0xa', cm.getValue()); - helpers.doKeys(''); - eq('0xb', cm.getValue()); - helpers.doKeys(''); - eq('0xc', cm.getValue()); - helpers.doKeys(''); - eq('0xd', cm.getValue()); - helpers.doKeys(''); - eq('0xe', cm.getValue()); - helpers.doKeys(''); - eq('0xf', cm.getValue()); - helpers.doKeys(''); - eq('0x10', cm.getValue()); - helpers.doKeys(''); - eq('0x0f', cm.getValue()); - helpers.doKeys(''); - eq('0x0e', cm.getValue()); - helpers.doKeys(''); - eq('0x0d', cm.getValue()); - helpers.doKeys(''); - eq('0x0c', cm.getValue()); - helpers.doKeys(''); - eq('0x0b', cm.getValue()); - helpers.doKeys(''); - eq('0x0a', cm.getValue()); - helpers.doKeys(''); - eq('0x09', cm.getValue()); - helpers.doKeys(''); - eq('0x08', cm.getValue()); - helpers.doKeys(''); - eq('0x07', cm.getValue()); - helpers.doKeys(''); - eq('0x06', cm.getValue()); - helpers.doKeys(''); - eq('0x05', cm.getValue()); - helpers.doKeys(''); - eq('0x04', cm.getValue()); - helpers.doKeys(''); - eq('0x03', cm.getValue()); - helpers.doKeys(''); - eq('0x02', cm.getValue()); - helpers.doKeys(''); - eq('0x01', cm.getValue()); - helpers.doKeys(''); - eq('0x00', cm.getValue()); - cm.setCursor(0, 0); - helpers.doKeys(''); - eq('0x01', cm.getValue()); - helpers.doKeys(''); - eq('0x02', cm.getValue()); - helpers.doKeys(''); - eq('0x01', cm.getValue()); - helpers.doKeys(''); - eq('0x00', cm.getValue()); -}, { value: '0x0' }); -}); - - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js deleted file mode 100644 index ccc6d3f7c94..00000000000 --- a/lib/ace/layer/cursor.js +++ /dev/null @@ -1,260 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var dom = require("../lib/dom"); - -var Cursor = function(parentEl) { - this.element = dom.createElement("div"); - this.element.className = "ace_layer ace_cursor-layer"; - parentEl.appendChild(this.element); - - this.isVisible = false; - this.isBlinking = true; - this.blinkInterval = 1000; - this.smoothBlinking = false; - - this.cursors = []; - this.cursor = this.addCursor(); - dom.addCssClass(this.element, "ace_hidden-cursors"); - this.$updateCursors = this.$updateOpacity.bind(this); -}; - -(function() { - - this.$updateOpacity = function(val) { - var cursors = this.cursors; - for (var i = cursors.length; i--; ) - dom.setStyle(cursors[i].style, "opacity", val ? "" : "0"); - }; - - this.$startCssAnimation = function() { - var cursors = this.cursors; - for (var i = cursors.length; i--; ) - cursors[i].style.animationDuration = this.blinkInterval + "ms"; - - setTimeout(function() { - dom.addCssClass(this.element, "ace_animate-blinking"); - }.bind(this)); - }; - - this.$stopCssAnimation = function() { - dom.removeCssClass(this.element, "ace_animate-blinking"); - }; - - this.$padding = 0; - this.setPadding = function(padding) { - this.$padding = padding; - }; - - this.setSession = function(session) { - this.session = session; - }; - - this.setBlinking = function(blinking) { - if (blinking != this.isBlinking) { - this.isBlinking = blinking; - this.restartTimer(); - } - }; - - this.setBlinkInterval = function(blinkInterval) { - if (blinkInterval != this.blinkInterval) { - this.blinkInterval = blinkInterval; - this.restartTimer(); - } - }; - - this.setSmoothBlinking = function(smoothBlinking) { - if (smoothBlinking != this.smoothBlinking) { - this.smoothBlinking = smoothBlinking; - dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking); - this.$updateCursors(true); - this.restartTimer(); - } - }; - - this.addCursor = function() { - var el = dom.createElement("div"); - el.className = "ace_cursor"; - this.element.appendChild(el); - this.cursors.push(el); - return el; - }; - - this.removeCursor = function() { - if (this.cursors.length > 1) { - var el = this.cursors.pop(); - el.parentNode.removeChild(el); - return el; - } - }; - - this.hideCursor = function() { - this.isVisible = false; - dom.addCssClass(this.element, "ace_hidden-cursors"); - this.restartTimer(); - }; - - this.showCursor = function() { - this.isVisible = true; - dom.removeCssClass(this.element, "ace_hidden-cursors"); - this.restartTimer(); - }; - - this.restartTimer = function() { - var update = this.$updateCursors; - clearInterval(this.intervalId); - clearTimeout(this.timeoutId); - this.$stopCssAnimation(); - - if (this.smoothBlinking) { - dom.removeCssClass(this.element, "ace_smooth-blinking"); - } - - update(true); - - if (!this.isBlinking || !this.blinkInterval || !this.isVisible) { - this.$stopCssAnimation(); - return; - } - - if (this.smoothBlinking) { - setTimeout(function(){ - dom.addCssClass(this.element, "ace_smooth-blinking"); - }.bind(this)); - } - - if (dom.HAS_CSS_ANIMATION) { - this.$startCssAnimation(); - } else { - var blink = function(){ - this.timeoutId = setTimeout(function() { - update(false); - }, 0.6 * this.blinkInterval); - }.bind(this); - - this.intervalId = setInterval(function() { - update(true); - blink(); - }, this.blinkInterval); - blink(); - } - }; - - this.getPixelPosition = function(position, onScreen) { - if (!this.config || !this.session) - return {left : 0, top : 0}; - - if (!position) - position = this.session.selection.getCursor(); - var pos = this.session.documentToScreenPosition(position); - var cursorLeft = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, position.row) - ? this.session.$bidiHandler.getPosLeft(pos.column) - : pos.column * this.config.characterWidth); - - var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * - this.config.lineHeight; - - return {left : cursorLeft, top : cursorTop}; - }; - - this.isCursorInView = function(pixelPos, config) { - return pixelPos.top >= 0 && pixelPos.top < config.maxHeight; - }; - - this.update = function(config) { - this.config = config; - - var selections = this.session.$selectionMarkers; - var i = 0, cursorIndex = 0; - - if (selections === undefined || selections.length === 0){ - selections = [{cursor: null}]; - } - - for (var i = 0, n = selections.length; i < n; i++) { - var pixelPos = this.getPixelPosition(selections[i].cursor, true); - if ((pixelPos.top > config.height + config.offset || - pixelPos.top < 0) && i > 1) { - continue; - } - - var element = this.cursors[cursorIndex++] || this.addCursor(); - var style = element.style; - - if (!this.drawCursor) { - if (!this.isCursorInView(pixelPos, config)) { - dom.setStyle(style, "display", "none"); - } else { - dom.setStyle(style, "display", "block"); - dom.translate(element, pixelPos.left, pixelPos.top); - dom.setStyle(style, "width", Math.round(config.characterWidth) + "px"); - dom.setStyle(style, "height", config.lineHeight + "px"); - } - } else { - this.drawCursor(element, pixelPos, config, selections[i], this.session); - } - } - while (this.cursors.length > cursorIndex) - this.removeCursor(); - - var overwrite = this.session.getOverwrite(); - this.$setOverwrite(overwrite); - - // cache for textarea and gutter highlight - this.$pixelPos = pixelPos; - this.restartTimer(); - }; - - this.drawCursor = null; - - this.$setOverwrite = function(overwrite) { - if (overwrite != this.overwrite) { - this.overwrite = overwrite; - if (overwrite) - dom.addCssClass(this.element, "ace_overwrite-cursors"); - else - dom.removeCssClass(this.element, "ace_overwrite-cursors"); - } - }; - - this.destroy = function() { - clearInterval(this.intervalId); - clearTimeout(this.timeoutId); - }; - -}).call(Cursor.prototype); - -exports.Cursor = Cursor; - -}); diff --git a/lib/ace/layer/font_metrics.js b/lib/ace/layer/font_metrics.js deleted file mode 100644 index 6864108f672..00000000000 --- a/lib/ace/layer/font_metrics.js +++ /dev/null @@ -1,236 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var oop = require("../lib/oop"); -var dom = require("../lib/dom"); -var lang = require("../lib/lang"); -var event = require("../lib/event"); -var useragent = require("../lib/useragent"); -var EventEmitter = require("../lib/event_emitter").EventEmitter; - -var CHAR_COUNT = 256; -var USE_OBSERVER = typeof ResizeObserver == "function"; -var L = 200; - -var FontMetrics = exports.FontMetrics = function(parentEl) { - this.el = dom.createElement("div"); - this.$setMeasureNodeStyles(this.el.style, true); - - this.$main = dom.createElement("div"); - this.$setMeasureNodeStyles(this.$main.style); - - this.$measureNode = dom.createElement("div"); - this.$setMeasureNodeStyles(this.$measureNode.style); - - - this.el.appendChild(this.$main); - this.el.appendChild(this.$measureNode); - parentEl.appendChild(this.el); - - this.$measureNode.innerHTML = lang.stringRepeat("X", CHAR_COUNT); - - this.$characterSize = {width: 0, height: 0}; - - - if (USE_OBSERVER) - this.$addObserver(); - else - this.checkForSizeChanges(); -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.$characterSize = {width: 0, height: 0}; - - this.$setMeasureNodeStyles = function(style, isRoot) { - style.width = style.height = "auto"; - style.left = style.top = "0px"; - style.visibility = "hidden"; - style.position = "absolute"; - style.whiteSpace = "pre"; - - if (useragent.isIE < 8) { - style["font-family"] = "inherit"; - } else { - style.font = "inherit"; - } - style.overflow = isRoot ? "hidden" : "visible"; - }; - - this.checkForSizeChanges = function(size) { - if (size === undefined) - size = this.$measureSizes(); - if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) { - this.$measureNode.style.fontWeight = "bold"; - var boldSize = this.$measureSizes(); - this.$measureNode.style.fontWeight = ""; - this.$characterSize = size; - this.charSizes = Object.create(null); - this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height; - this._emit("changeCharacterSize", {data: size}); - } - }; - - this.$addObserver = function() { - var self = this; - this.$observer = new window.ResizeObserver(function(e) { - var rect = e[0].contentRect; - self.checkForSizeChanges({ - height: rect.height, - width: rect.width / CHAR_COUNT - }); - }); - this.$observer.observe(this.$measureNode); - }; - - this.$pollSizeChanges = function() { - if (this.$pollSizeChangesTimer || this.$observer) - return this.$pollSizeChangesTimer; - var self = this; - - return this.$pollSizeChangesTimer = event.onIdle(function cb() { - self.checkForSizeChanges(); - event.onIdle(cb, 500); - }, 500); - }; - - this.setPolling = function(val) { - if (val) { - this.$pollSizeChanges(); - } else if (this.$pollSizeChangesTimer) { - clearInterval(this.$pollSizeChangesTimer); - this.$pollSizeChangesTimer = 0; - } - }; - - this.$measureSizes = function(node) { - var size = { - height: (node || this.$measureNode).clientHeight, - width: (node || this.$measureNode).clientWidth / CHAR_COUNT - }; - - // Size and width can be null if the editor is not visible or - // detached from the document - if (size.width === 0 || size.height === 0) - return null; - return size; - }; - - this.$measureCharWidth = function(ch) { - this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT); - var rect = this.$main.getBoundingClientRect(); - return rect.width / CHAR_COUNT; - }; - - this.getCharacterWidth = function(ch) { - var w = this.charSizes[ch]; - if (w === undefined) { - w = this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width; - } - return w; - }; - - this.destroy = function() { - clearInterval(this.$pollSizeChangesTimer); - if (this.el && this.el.parentNode) - this.el.parentNode.removeChild(this.el); - }; - - - this.$getZoom = function getZoom(element) { - if (!element) return 1; - return (window.getComputedStyle(element).zoom || 1) * getZoom(element.parentElement); - }; - this.$initTransformMeasureNodes = function() { - var t = function(t, l) { - return ["div", { - style: "position: absolute;top:" + t + "px;left:" + l + "px;" - }]; - }; - this.els = dom.buildDom([t(0, 0), t(L, 0), t(0, L), t(L, L)], this.el); - }; - // general transforms from element coordinates x to screen coordinates u have the form - // | m1[0] m2[0] t[0] | | x | | u | - // | m1[1] m2[1] t[1] | . | y | == k | v | - // | h[0] h[1] 1 | | 1 | | 1 | - // this function finds the coeeficients of the matrix using positions of four points - // - this.transformCoordinates = function(clientPos, elPos) { - if (clientPos) { - var zoom = this.$getZoom(this.el); - clientPos = mul(1 / zoom, clientPos); - } - function solve(l1, l2, r) { - var det = l1[1] * l2[0] - l1[0] * l2[1]; - return [ - (-l2[1] * r[0] + l2[0] * r[1]) / det, - (+l1[1] * r[0] - l1[0] * r[1]) / det - ]; - } - function sub(a, b) { return [a[0] - b[0], a[1] - b[1]]; } - function add(a, b) { return [a[0] + b[0], a[1] + b[1]]; } - function mul(a, b) { return [a * b[0], a * b[1]]; } - - if (!this.els) - this.$initTransformMeasureNodes(); - - function p(el) { - var r = el.getBoundingClientRect(); - return [r.left, r.top]; - } - - var a = p(this.els[0]); - var b = p(this.els[1]); - var c = p(this.els[2]); - var d = p(this.els[3]); - - var h = solve(sub(d, b), sub(d, c), sub(add(b, c), add(d, a))); - - var m1 = mul(1 + h[0], sub(b, a)); - var m2 = mul(1 + h[1], sub(c, a)); - - if (elPos) { - var x = elPos; - var k = h[0] * x[0] / L + h[1] * x[1] / L + 1; - var ut = add(mul(x[0], m1), mul(x[1], m2)); - return add(mul(1 / k / L, ut), a); - } - var u = sub(clientPos, a); - var f = solve(sub(m1, mul(h[0], u)), sub(m2, mul(h[1], u)), u); - return mul(L, f); - }; - -}).call(FontMetrics.prototype); - -}); diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js deleted file mode 100644 index 4d11eb30888..00000000000 --- a/lib/ace/layer/gutter.js +++ /dev/null @@ -1,448 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var dom = require("../lib/dom"); -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var EventEmitter = require("../lib/event_emitter").EventEmitter; -var Lines = require("./lines").Lines; - -var Gutter = function(parentEl) { - this.element = dom.createElement("div"); - this.element.className = "ace_layer ace_gutter-layer"; - parentEl.appendChild(this.element); - this.setShowFoldWidgets(this.$showFoldWidgets); - - this.gutterWidth = 0; - - this.$annotations = []; - this.$updateAnnotations = this.$updateAnnotations.bind(this); - - this.$lines = new Lines(this.element); - this.$lines.$offsetCoefficient = 1; -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.setSession = function(session) { - if (this.session) - this.session.removeEventListener("change", this.$updateAnnotations); - this.session = session; - if (session) - session.on("change", this.$updateAnnotations); - }; - - this.addGutterDecoration = function(row, className) { - if (window.console) - console.warn && console.warn("deprecated use session.addGutterDecoration"); - this.session.addGutterDecoration(row, className); - }; - - this.removeGutterDecoration = function(row, className) { - if (window.console) - console.warn && console.warn("deprecated use session.removeGutterDecoration"); - this.session.removeGutterDecoration(row, className); - }; - - this.setAnnotations = function(annotations) { - // iterate over sparse array - this.$annotations = []; - for (var i = 0; i < annotations.length; i++) { - var annotation = annotations[i]; - var row = annotation.row; - var rowInfo = this.$annotations[row]; - if (!rowInfo) - rowInfo = this.$annotations[row] = {text: []}; - - var annoText = annotation.text; - annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || ""; - - if (rowInfo.text.indexOf(annoText) === -1) - rowInfo.text.push(annoText); - - var type = annotation.type; - if (type == "error") - rowInfo.className = " ace_error"; - else if (type == "warning" && rowInfo.className != " ace_error") - rowInfo.className = " ace_warning"; - else if (type == "info" && (!rowInfo.className)) - rowInfo.className = " ace_info"; - } - }; - - this.$updateAnnotations = function (delta) { - if (!this.$annotations.length) - return; - var firstRow = delta.start.row; - var len = delta.end.row - firstRow; - if (len === 0) { - // do nothing - } else if (delta.action == 'remove') { - this.$annotations.splice(firstRow, len + 1, null); - } else { - var args = new Array(len + 1); - args.unshift(firstRow, 1); - this.$annotations.splice.apply(this.$annotations, args); - } - }; - - this.update = function(config) { - this.config = config; - - var session = this.session; - var firstRow = config.firstRow; - var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar - session.getLength() - 1); - - this.oldLastRow = lastRow; - this.config = config; - - this.$lines.moveContainer(config); - this.$updateCursorRow(); - - var fold = session.getNextFoldLine(firstRow); - var foldStart = fold ? fold.start.row : Infinity; - - var cell = null; - var index = -1; - var row = firstRow; - - var cells = Array.prototype.slice.call(this.element.childNodes, 0); - - while (true) { - if (row > foldStart) { - row = fold.end.row + 1; - fold = session.getNextFoldLine(row, fold); - foldStart = fold ? fold.start.row : Infinity; - } - if (row > lastRow) { - while (this.$lines.getLength() > index + 1) - this.$lines.pop(); - - break; - } - - cell = this.$lines.get(++index); - if (!cell) { - cell = this.$lines.createCell(row, config, this.session, onCreateCell); - this.$lines.push(cell); - } - - this.$renderCell(cell, config, fold, row); - row++; - } - - this.$updateGutterWidth(config); - }; - - this.$updateGutterWidth = function(config) { - var session = this.session; - - var gutterRenderer = session.gutterRenderer || this.$renderer; - - var firstLineNumber = session.$firstLineNumber; - var lastLineText = this.$lines.last() ? this.$lines.last().text : ""; - - if (this.$fixedWidth || session.$useWrapMode) - lastLineText = session.getLength() + firstLineNumber; - - var gutterWidth = gutterRenderer - ? gutterRenderer.getWidth(session, lastLineText, config) - : lastLineText.toString().length * config.characterWidth; - - var padding = this.$padding || this.$computePadding(); - gutterWidth += padding.left + padding.right; - if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) { - this.gutterWidth = gutterWidth; - this.element.parentNode.style.width = - this.element.style.width = Math.ceil(this.gutterWidth) + "px"; - this._signal("changeGutterWidth", gutterWidth); - } - }; - - this.$updateCursorRow = function() { - if (!this.$highlightGutterLine) - return; - - var position = this.session.selection.getCursor(); - if (this.$cursorRow === position.row) - return; - - this.$cursorRow = position.row; - }; - - this.updateLineHighlight = function() { - if (!this.$highlightGutterLine) - return; - var row = this.session.selection.cursor.row; - this.$cursorRow = row; - - if (this.$cursorCell && this.$cursorCell.row == row) - return; - if (this.$cursorCell) - this.$cursorCell.element.className = this.$cursorCell.element.className.replace("ace_gutter-active-line ", ""); - var cells = this.$lines.cells; - this.$cursorCell = null; - for (var i = 0; i < cells.length; i++) { - var cell = cells[i]; - if (cell.row >= this.$cursorRow) { - if (cell.row > this.$cursorRow) { - var fold = this.session.getFoldLine(this.$cursorRow); - if (i > 0 && fold && fold.start.row == cells[i - 1].row) - cell = cells[i - 1]; - else - break; - } - cell.element.className = "ace_gutter-active-line " + cell.element.className; - this.$cursorCell = cell; - break; - } - } - }; - - this.scrollLines = function(config) { - var oldConfig = this.config; - this.config = config; - - this.$updateCursorRow(); - if (this.$lines.pageChanged(oldConfig, config)) - return this.update(config); - - this.$lines.moveContainer(config); - - var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar - this.session.getLength() - 1); - var oldLastRow = this.oldLastRow; - this.oldLastRow = lastRow; - - if (!oldConfig || oldLastRow < config.firstRow) - return this.update(config); - - if (lastRow < oldConfig.firstRow) - return this.update(config); - - if (oldConfig.firstRow < config.firstRow) - for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--) - this.$lines.shift(); - - if (oldLastRow > lastRow) - for (var row=this.session.getFoldedRowCount(lastRow + 1, oldLastRow); row>0; row--) - this.$lines.pop(); - - if (config.firstRow < oldConfig.firstRow) { - this.$lines.unshift(this.$renderLines(config, config.firstRow, oldConfig.firstRow - 1)); - } - - if (lastRow > oldLastRow) { - this.$lines.push(this.$renderLines(config, oldLastRow + 1, lastRow)); - } - - this.updateLineHighlight(); - - this.$updateGutterWidth(config); - }; - - this.$renderLines = function(config, firstRow, lastRow) { - var fragment = []; - var row = firstRow; - var foldLine = this.session.getNextFoldLine(row); - var foldStart = foldLine ? foldLine.start.row : Infinity; - - while (true) { - if (row > foldStart) { - row = foldLine.end.row+1; - foldLine = this.session.getNextFoldLine(row, foldLine); - foldStart = foldLine ? foldLine.start.row : Infinity; - } - if (row > lastRow) - break; - - var cell = this.$lines.createCell(row, config, this.session, onCreateCell); - this.$renderCell(cell, config, foldLine, row); - fragment.push(cell); - - row++; - } - return fragment; - }; - - this.$renderCell = function(cell, config, fold, row) { - var element = cell.element; - - var session = this.session; - - var textNode = element.childNodes[0]; - var foldWidget = element.childNodes[1]; - - var firstLineNumber = session.$firstLineNumber; - - var session = this.session; - var breakpoints = session.$breakpoints; - var decorations = session.$decorations; - var gutterRenderer = session.gutterRenderer || this.$renderer; - var foldWidgets = this.$showFoldWidgets && session.foldWidgets; - var foldStart = fold ? fold.start.row : Number.MAX_VALUE; - - var className = "ace_gutter-cell "; - if (this.$highlightGutterLine) { - if (row == this.$cursorRow || (fold && row < this.$cursorRow && row >= foldStart && this.$cursorRow <= fold.end.row)) { - className += "ace_gutter-active-line "; - if (this.$cursorCell != cell) { - if (this.$cursorCell) - this.$cursorCell.element.className = this.$cursorCell.element.className.replace("ace_gutter-active-line ", ""); - this.$cursorCell = cell; - } - } - } - - if (breakpoints[row]) - className += breakpoints[row]; - if (decorations[row]) - className += decorations[row]; - if (this.$annotations[row]) - className += this.$annotations[row].className; - if (element.className != className) - element.className = className; - - if (foldWidgets) { - var c = foldWidgets[row]; - // check if cached value is invalidated and we need to recompute - if (c == null) - c = foldWidgets[row] = session.getFoldWidget(row); - } - - if (c) { - var className = "ace_fold-widget ace_" + c; - if (c == "start" && row == foldStart && row < fold.end.row) - className += " ace_closed"; - else - className += " ace_open"; - if (foldWidget.className != className) - foldWidget.className = className; - - var foldHeight = config.lineHeight + "px"; - dom.setStyle(foldWidget.style, "height", foldHeight); - dom.setStyle(foldWidget.style, "display", "inline-block"); - } else { - if (foldWidget) { - dom.setStyle(foldWidget.style, "display", "none"); - } - } - - var text = (gutterRenderer - ? gutterRenderer.getText(session, row) - : row + firstLineNumber).toString(); - - if (text !== textNode.data) { - textNode.data = text; - } - - dom.setStyle(cell.element.style, "height", this.$lines.computeLineHeight(row, config, session) + "px"); - dom.setStyle(cell.element.style, "top", this.$lines.computeLineTop(row, config, session) + "px"); - - cell.text = text; - return cell; - }; - - this.$fixedWidth = false; - - this.$highlightGutterLine = true; - this.$renderer = ""; - this.setHighlightGutterLine = function(highlightGutterLine) { - this.$highlightGutterLine = highlightGutterLine; - }; - - this.$showLineNumbers = true; - this.$renderer = ""; - this.setShowLineNumbers = function(show) { - this.$renderer = !show && { - getWidth: function() {return "";}, - getText: function() {return "";} - }; - }; - - this.getShowLineNumbers = function() { - return this.$showLineNumbers; - }; - - this.$showFoldWidgets = true; - this.setShowFoldWidgets = function(show) { - if (show) - dom.addCssClass(this.element, "ace_folding-enabled"); - else - dom.removeCssClass(this.element, "ace_folding-enabled"); - - this.$showFoldWidgets = show; - this.$padding = null; - }; - - this.getShowFoldWidgets = function() { - return this.$showFoldWidgets; - }; - - this.$computePadding = function() { - if (!this.element.firstChild) - return {left: 0, right: 0}; - var style = dom.computedStyle(this.element.firstChild); - this.$padding = {}; - this.$padding.left = parseInt(style.paddingLeft) + 1 || 0; - this.$padding.right = parseInt(style.paddingRight) || 0; - return this.$padding; - }; - - this.getRegion = function(point) { - var padding = this.$padding || this.$computePadding(); - var rect = this.element.getBoundingClientRect(); - if (point.x < padding.left + rect.left) - return "markers"; - if (this.$showFoldWidgets && point.x > rect.right - padding.right) - return "foldWidgets"; - }; - -}).call(Gutter.prototype); - -function onCreateCell(element) { - var textNode = document.createTextNode(''); - element.appendChild(textNode); - - var foldWidget = dom.createElement("span"); - element.appendChild(foldWidget); - - return element; -} - -exports.Gutter = Gutter; - -}); diff --git a/lib/ace/layer/lines.js b/lib/ace/layer/lines.js deleted file mode 100644 index c29a78d38bf..00000000000 --- a/lib/ace/layer/lines.js +++ /dev/null @@ -1,156 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var dom = require("../lib/dom"); - -var Lines = function(element, canvasHeight) { - this.element = element; - this.canvasHeight = canvasHeight || 500000; - this.element.style.height = (this.canvasHeight * 2) + "px"; - - this.cells = []; - this.cellCache = []; - this.$offsetCoefficient = 0; -}; - -(function() { - - this.moveContainer = function(config) { - dom.translate(this.element, 0, -((config.firstRowScreen * config.lineHeight) % this.canvasHeight) - config.offset * this.$offsetCoefficient); - }; - - this.pageChanged = function(oldConfig, newConfig) { - return ( - Math.floor((oldConfig.firstRowScreen * oldConfig.lineHeight) / this.canvasHeight) !== - Math.floor((newConfig.firstRowScreen * newConfig.lineHeight) / this.canvasHeight) - ); - }; - - this.computeLineTop = function(row, config, session) { - var screenTop = config.firstRowScreen * config.lineHeight; - var screenPage = Math.floor(screenTop / this.canvasHeight); - var lineTop = session.documentToScreenRow(row, 0) * config.lineHeight; - return lineTop - (screenPage * this.canvasHeight); - }; - - this.computeLineHeight = function(row, config, session) { - return config.lineHeight * session.getRowLength(row); - }; - - this.getLength = function() { - return this.cells.length; - }; - - this.get = function(index) { - return this.cells[index]; - }; - - this.shift = function() { - this.$cacheCell(this.cells.shift()); - }; - - this.pop = function() { - this.$cacheCell(this.cells.pop()); - }; - - this.push = function(cell) { - if (Array.isArray(cell)) { - this.cells.push.apply(this.cells, cell); - var fragment = dom.createFragment(this.element); - for (var i=0; i next, row == end), - layerConfig, row == end ? 0 : 1, extraStyle); - } - }; - - // Draws a multi line marker, where lines span the full width - this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { - // from selection start to the end of the line - var padding = this.$padding; - var height = config.lineHeight; - var top = this.$getTop(range.start.row, config); - var left = padding + range.start.column * config.characterWidth; - extraStyle = extraStyle || ""; - - this.elt( - clazz + " ace_br1 ace_start", - "height:"+ height+ "px;"+ "right:0;"+ "top:"+top+ "px;left:"+ left+ "px;" + (extraStyle || "") - ); - - // from start of the last line to the selection end - top = this.$getTop(range.end.row, config); - var width = range.end.column * config.characterWidth; - - this.elt( - clazz + " ace_br12", - "height:"+ height+ "px;"+ - "width:"+ width+ "px;"+ - "top:"+ top+ "px;"+ - "left:"+ padding+ "px;"+ (extraStyle || "") - ); - - // all the complete lines - height = (range.end.row - range.start.row - 1) * config.lineHeight; - if (height <= 0) - return; - top = this.$getTop(range.start.row + 1, config); - - var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8); - - this.elt( - clazz + (radiusClass ? " ace_br" + radiusClass : ""), - "height:"+ height+ "px;"+ - "right:0;"+ - "top:"+ top+ "px;"+ - "left:"+ padding+ "px;"+ (extraStyle || "") - ); - }; - - // Draws a marker which covers part or whole width of a single screen line - this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) { - var height = config.lineHeight; - var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth; - - var top = this.$getTop(range.start.row, config); - var left = this.$padding + range.start.column * config.characterWidth; - - this.elt( - clazz, - "height:"+ height+ "px;"+ - "width:"+ width+ "px;"+ - "top:"+ top+ "px;"+ - "left:"+ left+ "px;"+ (extraStyle || "") - ); - }; - - this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { - var top = this.$getTop(range.start.row, config); - var height = config.lineHeight; - if (range.start.row != range.end.row) - height += this.$getTop(range.end.row, config) - top; - - this.elt( - clazz, - "height:"+ height+ "px;"+ - "top:"+ top+ "px;"+ - "left:0;right:0;"+ (extraStyle || "") - ); - }; - - this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { - var top = this.$getTop(range.start.row, config); - var height = config.lineHeight; - - this.elt( - clazz, - "height:"+ height+ "px;"+ - "top:"+ top+ "px;"+ - "left:0;right:0;"+ (extraStyle || "") - ); - }; - -}).call(Marker.prototype); - -exports.Marker = Marker; - -}); \ No newline at end of file diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js deleted file mode 100644 index 13980d0e70f..00000000000 --- a/lib/ace/layer/text.js +++ /dev/null @@ -1,649 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var dom = require("../lib/dom"); -var lang = require("../lib/lang"); -var Lines = require("./lines").Lines; -var EventEmitter = require("../lib/event_emitter").EventEmitter; - -var Text = function(parentEl) { - this.dom = dom; - this.element = this.dom.createElement("div"); - this.element.className = "ace_layer ace_text-layer"; - parentEl.appendChild(this.element); - this.$updateEolChar = this.$updateEolChar.bind(this); - this.$lines = new Lines(this.element); -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.EOF_CHAR = "\xB6"; - this.EOL_CHAR_LF = "\xAC"; - this.EOL_CHAR_CRLF = "\xa4"; - this.EOL_CHAR = this.EOL_CHAR_LF; - this.TAB_CHAR = "\u2014"; //"\u21E5"; - this.SPACE_CHAR = "\xB7"; - this.$padding = 0; - this.MAX_LINE_LENGTH = 10000; - - this.$updateEolChar = function() { - var doc = this.session.doc; - var unixMode = doc.getNewLineCharacter() == "\n" && doc.getNewLineMode() != "windows"; - var EOL_CHAR = unixMode ? this.EOL_CHAR_LF : this.EOL_CHAR_CRLF; - if (this.EOL_CHAR != EOL_CHAR) { - this.EOL_CHAR = EOL_CHAR; - return true; - } - }; - - this.setPadding = function(padding) { - this.$padding = padding; - this.element.style.margin = "0 " + padding + "px"; - }; - - this.getLineHeight = function() { - return this.$fontMetrics.$characterSize.height || 0; - }; - - this.getCharacterWidth = function() { - return this.$fontMetrics.$characterSize.width || 0; - }; - - this.$setFontMetrics = function(measure) { - this.$fontMetrics = measure; - this.$fontMetrics.on("changeCharacterSize", function(e) { - this._signal("changeCharacterSize", e); - }.bind(this)); - this.$pollSizeChanges(); - }; - - this.checkForSizeChanges = function() { - this.$fontMetrics.checkForSizeChanges(); - }; - this.$pollSizeChanges = function() { - return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges(); - }; - this.setSession = function(session) { - this.session = session; - if (session) - this.$computeTabString(); - }; - - this.showInvisibles = false; - this.setShowInvisibles = function(showInvisibles) { - if (this.showInvisibles == showInvisibles) - return false; - - this.showInvisibles = showInvisibles; - this.$computeTabString(); - return true; - }; - - this.displayIndentGuides = true; - this.setDisplayIndentGuides = function(display) { - if (this.displayIndentGuides == display) - return false; - - this.displayIndentGuides = display; - this.$computeTabString(); - return true; - }; - - this.$tabStrings = []; - this.onChangeTabSize = - this.$computeTabString = function() { - var tabSize = this.session.getTabSize(); - this.tabSize = tabSize; - var tabStr = this.$tabStrings = [0]; - for (var i = 1; i < tabSize + 1; i++) { - if (this.showInvisibles) { - var span = this.dom.createElement("span"); - span.className = "ace_invisible ace_invisible_tab"; - span.textContent = lang.stringRepeat(this.TAB_CHAR, i); - tabStr.push(span); - } else { - tabStr.push(this.dom.createTextNode(lang.stringRepeat(" ", i), this.element)); - } - } - if (this.displayIndentGuides) { - this.$indentGuideRe = /\s\S| \t|\t |\s$/; - var className = "ace_indent-guide"; - var spaceClass = ""; - var tabClass = ""; - if (this.showInvisibles) { - className += " ace_invisible"; - spaceClass = " ace_invisible_space"; - tabClass = " ace_invisible_tab"; - var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize); - var tabContent = lang.stringRepeat(this.TAB_CHAR, this.tabSize); - } else { - var spaceContent = lang.stringRepeat(" ", this.tabSize); - var tabContent = spaceContent; - } - - var span = this.dom.createElement("span"); - span.className = className + spaceClass; - span.textContent = spaceContent; - this.$tabStrings[" "] = span; - - var span = this.dom.createElement("span"); - span.className = className + tabClass; - span.textContent = tabContent; - this.$tabStrings["\t"] = span; - } - }; - - this.updateLines = function(config, firstRow, lastRow) { - // Due to wrap line changes there can be new lines if e.g. - // the line to updated wrapped in the meantime. - if (this.config.lastRow != config.lastRow || - this.config.firstRow != config.firstRow) { - return this.update(config); - } - - this.config = config; - - var first = Math.max(firstRow, config.firstRow); - var last = Math.min(lastRow, config.lastRow); - - var lineElements = this.element.childNodes; - var lineElementsIdx = 0; - - for (var row = config.firstRow; row < first; row++) { - var foldLine = this.session.getFoldLine(row); - if (foldLine) { - if (foldLine.containsRow(first)) { - first = foldLine.start.row; - break; - } else { - row = foldLine.end.row; - } - } - lineElementsIdx ++; - } - - var heightChanged = false; - var row = first; - var foldLine = this.session.getNextFoldLine(row); - var foldStart = foldLine ? foldLine.start.row : Infinity; - - while (true) { - if (row > foldStart) { - row = foldLine.end.row+1; - foldLine = this.session.getNextFoldLine(row, foldLine); - foldStart = foldLine ? foldLine.start.row :Infinity; - } - if (row > last) - break; - - var lineElement = lineElements[lineElementsIdx++]; - if (lineElement) { - this.dom.removeChildren(lineElement); - this.$renderLine( - lineElement, row, row == foldStart ? foldLine : false - ); - var height = (config.lineHeight * this.session.getRowLength(row)) + "px"; - if (lineElement.style.height != height) { - heightChanged = true; - lineElement.style.height = height; - } - } - row++; - } - if (heightChanged) { - while (lineElementsIdx < this.$lines.cells.length) { - var cell = this.$lines.cells[lineElementsIdx++]; - cell.element.style.top = this.$lines.computeLineTop(cell.row, config, this.session) + "px"; - } - } - }; - - this.scrollLines = function(config) { - var oldConfig = this.config; - this.config = config; - - if (this.$lines.pageChanged(oldConfig, config)) - return this.update(config); - - this.$lines.moveContainer(config); - - var lastRow = config.lastRow; - var oldLastRow = oldConfig ? oldConfig.lastRow : -1; - - if (!oldConfig || oldLastRow < config.firstRow) - return this.update(config); - - if (lastRow < oldConfig.firstRow) - return this.update(config); - - if (!oldConfig || oldConfig.lastRow < config.firstRow) - return this.update(config); - - if (config.lastRow < oldConfig.firstRow) - return this.update(config); - - if (oldConfig.firstRow < config.firstRow) - for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--) - this.$lines.shift(); - - if (oldConfig.lastRow > config.lastRow) - for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--) - this.$lines.pop(); - - if (config.firstRow < oldConfig.firstRow) { - this.$lines.unshift(this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1)); - } - - if (config.lastRow > oldConfig.lastRow) { - this.$lines.push(this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow)); - } - }; - - this.$renderLinesFragment = function(config, firstRow, lastRow) { - var fragment = []; - var row = firstRow; - var foldLine = this.session.getNextFoldLine(row); - var foldStart = foldLine ? foldLine.start.row : Infinity; - - while (true) { - if (row > foldStart) { - row = foldLine.end.row+1; - foldLine = this.session.getNextFoldLine(row, foldLine); - foldStart = foldLine ? foldLine.start.row : Infinity; - } - if (row > lastRow) - break; - - var line = this.$lines.createCell(row, config, this.session); - - var lineEl = line.element; - this.dom.removeChildren(lineEl); - dom.setStyle(lineEl.style, "height", this.$lines.computeLineHeight(row, config, this.session) + "px"); - dom.setStyle(lineEl.style, "top", this.$lines.computeLineTop(row, config, this.session) + "px"); - - // Get the tokens per line as there might be some lines in between - // beeing folded. - this.$renderLine(lineEl, row, row == foldStart ? foldLine : false); - - if (this.$useLineGroups()) { - lineEl.className = "ace_line_group"; - } else { - lineEl.className = "ace_line"; - } - fragment.push(line); - - row++; - } - return fragment; - }; - - this.update = function(config) { - this.$lines.moveContainer(config); - - this.config = config; - - var firstRow = config.firstRow; - var lastRow = config.lastRow; - - var lines = this.$lines; - while (lines.getLength()) - lines.pop(); - - lines.push(this.$renderLinesFragment(config, firstRow, lastRow)); - }; - - this.$textToken = { - "text": true, - "rparen": true, - "lparen": true - }; - - this.$renderToken = function(parent, screenColumn, token, value) { - var self = this; - var re = /(\t)|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\uFEFF\uFFF9-\uFFFC]+)|(\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; - - var valueFragment = this.dom.createFragment(this.element); - - var m; - var i = 0; - while (m = re.exec(value)) { - var tab = m[1]; - var simpleSpace = m[2]; - var controlCharacter = m[3]; - var cjkSpace = m[4]; - var cjk = m[5]; - - if (!self.showInvisibles && simpleSpace) - continue; - - var before = i != m.index ? value.slice(i, m.index) : ""; - - i = m.index + m[0].length; - - if (before) { - valueFragment.appendChild(this.dom.createTextNode(before, this.element)); - } - - if (tab) { - var tabSize = self.session.getScreenTabSize(screenColumn + m.index); - valueFragment.appendChild(self.$tabStrings[tabSize].cloneNode(true)); - screenColumn += tabSize - 1; - } else if (simpleSpace) { - if (self.showInvisibles) { - var span = this.dom.createElement("span"); - span.className = "ace_invisible ace_invisible_space"; - span.textContent = lang.stringRepeat(self.SPACE_CHAR, simpleSpace.length); - valueFragment.appendChild(span); - } else { - valueFragment.appendChild(this.com.createTextNode(simpleSpace, this.element)); - } - } else if (controlCharacter) { - var span = this.dom.createElement("span"); - span.className = "ace_invisible ace_invisible_space ace_invalid"; - span.textContent = lang.stringRepeat(self.SPACE_CHAR, controlCharacter.length); - valueFragment.appendChild(span); - } else if (cjkSpace) { - // U+3000 is both invisible AND full-width, so must be handled uniquely - var space = self.showInvisibles ? self.SPACE_CHAR : ""; - screenColumn += 1; - - var span = this.dom.createElement("span"); - span.style.width = (self.config.characterWidth * 2) + "px"; - span.className = self.showInvisibles ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk"; - span.textContent = self.showInvisibles ? self.SPACE_CHAR : ""; - valueFragment.appendChild(span); - } else if (cjk) { - screenColumn += 1; - var span = dom.createElement("span"); - span.style.width = (self.config.characterWidth * 2) + "px"; - span.className = "ace_cjk"; - span.textContent = cjk; - valueFragment.appendChild(span); - } - } - - valueFragment.appendChild(this.dom.createTextNode(i ? value.slice(i) : value, this.element)); - - if (!this.$textToken[token.type]) { - var classes = "ace_" + token.type.replace(/\./g, " ace_"); - var span = this.dom.createElement("span"); - if (token.type == "fold") - span.style.width = (token.value.length * this.config.characterWidth) + "px"; - - span.className = classes; - span.appendChild(valueFragment); - - parent.appendChild(span); - } - else { - parent.appendChild(valueFragment); - } - - return screenColumn + value.length; - }; - - this.renderIndentGuide = function(parent, value, max) { - var cols = value.search(this.$indentGuideRe); - if (cols <= 0 || cols >= max) - return value; - if (value[0] == " ") { - cols -= cols % this.tabSize; - var count = cols/this.tabSize; - for (var i=0; i= splitChars) { - screenColumn = this.$renderToken( - lineEl, screenColumn, - token, value.substring(0, splitChars - chars) - ); - value = value.substring(splitChars - chars); - chars = splitChars; - - lineEl = this.$createLineElement(); - parent.appendChild(lineEl); - - lineEl.appendChild(this.dom.createTextNode(lang.stringRepeat("\xa0", splits.indent), this.element)); - - split ++; - screenColumn = 0; - splitChars = splits[split] || Number.MAX_VALUE; - } - if (value.length != 0) { - chars += value.length; - screenColumn = this.$renderToken( - lineEl, screenColumn, token, value - ); - } - } - } - }; - - this.$renderSimpleLine = function(parent, tokens) { - var screenColumn = 0; - var token = tokens[0]; - var value = token.value; - if (this.displayIndentGuides) - value = this.renderIndentGuide(parent, value); - if (value) - screenColumn = this.$renderToken(parent, screenColumn, token, value); - for (var i = 1; i < tokens.length; i++) { - token = tokens[i]; - value = token.value; - if (screenColumn + value.length > this.MAX_LINE_LENGTH) - return this.$renderOverflowMessage(parent, screenColumn, token, value); - screenColumn = this.$renderToken(parent, screenColumn, token, value); - } - }; - - this.$renderOverflowMessage = function(parent, screenColumn, token, value) { - this.$renderToken(parent, screenColumn, token, - value.slice(0, this.MAX_LINE_LENGTH - screenColumn)); - - var overflowEl = this.dom.createElement("span"); - overflowEl.className = "ace_inline_button ace_keyword ace_toggle_wrap"; - overflowEl.style.position = "absolute"; - overflowEl.style.right = "0"; - overflowEl.textContent = ""; - - parent.appendChild(overflowEl); - }; - - // row is either first row of foldline or not in fold - this.$renderLine = function(parent, row, foldLine) { - if (!foldLine && foldLine != false) - foldLine = this.session.getFoldLine(row); - - if (foldLine) - var tokens = this.$getFoldLineTokens(row, foldLine); - else - var tokens = this.session.getTokens(row); - - var lastLineEl = parent; - if (tokens.length) { - var splits = this.session.getRowSplitData(row); - if (splits && splits.length) { - this.$renderWrappedLine(parent, tokens, splits); - var lastLineEl = parent.lastChild; - } else { - var lastLineEl = parent; - if (this.$useLineGroups()) { - lastLineEl = this.$createLineElement(); - parent.appendChild(lastLineEl); - } - this.$renderSimpleLine(lastLineEl, tokens); - } - } else if (this.$useLineGroups()) { - lastLineEl = this.$createLineElement(); - parent.appendChild(lastLineEl); - } - - if (this.showInvisibles && lastLineEl) { - if (foldLine) - row = foldLine.end.row; - - var invisibleEl = this.dom.createElement("span"); - invisibleEl.className = "ace_invisible ace_invisible_eol"; - invisibleEl.textContent = row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR; - - lastLineEl.appendChild(invisibleEl); - } - }; - - this.$getFoldLineTokens = function(row, foldLine) { - var session = this.session; - var renderTokens = []; - - function addTokens(tokens, from, to) { - var idx = 0, col = 0; - while ((col + tokens[idx].value.length) < from) { - col += tokens[idx].value.length; - idx++; - - if (idx == tokens.length) - return; - } - if (col != from) { - var value = tokens[idx].value.substring(from - col); - // Check if the token value is longer then the from...to spacing. - if (value.length > (to - from)) - value = value.substring(0, to - from); - - renderTokens.push({ - type: tokens[idx].type, - value: value - }); - - col = from + value.length; - idx += 1; - } - - while (col < to && idx < tokens.length) { - var value = tokens[idx].value; - if (value.length + col > to) { - renderTokens.push({ - type: tokens[idx].type, - value: value.substring(0, to - col) - }); - } else - renderTokens.push(tokens[idx]); - col += value.length; - idx += 1; - } - } - - var tokens = session.getTokens(row); - foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) { - if (placeholder != null) { - renderTokens.push({ - type: "fold", - value: placeholder - }); - } else { - if (isNewRow) - tokens = session.getTokens(row); - - if (tokens.length) - addTokens(tokens, lastColumn, column); - } - }, foldLine.end.row, this.session.getLine(foldLine.end.row).length); - - return renderTokens; - }; - - this.$useLineGroups = function() { - // For the updateLines function to work correctly, it's important that the - // child nodes of this.element correspond on a 1-to-1 basis to rows in the - // document (as distinct from lines on the screen). For sessions that are - // wrapped, this means we need to add a layer to the node hierarchy (tagged - // with the class name ace_line_group). - return this.session.getUseWrapMode(); - }; - - this.destroy = function() { - clearInterval(this.$pollSizeChangesTimer); - if (this.$measureNode) - this.$measureNode.parentNode.removeChild(this.$measureNode); - delete this.$measureNode; - }; - -}).call(Text.prototype); - -exports.Text = Text; - -}); diff --git a/lib/ace/layer/text_test.js b/lib/ace/layer/text_test.js deleted file mode 100644 index aa94482106d..00000000000 --- a/lib/ace/layer/text_test.js +++ /dev/null @@ -1,129 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") { - require("amd-loader"); - require("../test/mockdom"); -} - -define(function(require, exports, module) { -"use strict"; - -var assert = require("../test/assertions"); -var EditSession = require("../edit_session").EditSession; -var TextLayer = require("./text").Text; -var JavaScriptMode = require("../mode/javascript").Mode; -var dom = require("../lib/dom"); - -module.exports = { - - setUp: function(next) { - this.session = new EditSession(""); - this.session.setMode(new JavaScriptMode()); - this.textLayer = new TextLayer(document.createElement("div")); - this.textLayer.setSession(this.session); - this.textLayer.config = { - characterWidth: 10, - lineHeight: 20 - }; - next(); - }, - - "test: render line with hard tabs should render the same as lines with soft tabs" : function() { - this.session.setValue("a\ta\ta\t\na a a \n"); - this.textLayer.$computeTabString(); - - // row with hard tabs - var parent1 = dom.createElement("div"); - this.textLayer.$renderLine(parent1, 0); - - // row with soft tabs - var parent2 = dom.createElement("div"); - this.textLayer.$renderLine(parent2, 1); - assert.equal(parent1.innerHTML, parent2.innerHTML); - }, - - "test rendering width of ideographic space (U+3000)" : function() { - this.session.setValue("\u3000"); - - var parent = dom.createElement("div"); - this.textLayer.$renderLine(parent, 0); - assert.domNode(parent, ["div", {}, ["span", {class: "ace_cjk", style: "width: 20px;"}]]); - - this.textLayer.setShowInvisibles(true); - var parent = dom.createElement("div"); - this.textLayer.$renderLine(parent, 0); - assert.domNode(parent, ["div", {}, - ["span", {class: "ace_cjk ace_invisible ace_invisible_space", style: "width: 20px;"}, this.textLayer.SPACE_CHAR], - ["span", {class: "ace_invisible ace_invisible_eol"}, "\xB6"] - ]); - }, - - "test rendering of indent guides" : function() { - var textLayer = this.textLayer; - var EOL = "" + textLayer.EOL_CHAR + ""; - var SPACE = function(i) {return Array(i+1).join(" ");}; - var DOT = function(i) {return Array(i+1).join(textLayer.SPACE_CHAR);}; - var TAB = function(i) {return Array(i+1).join(textLayer.TAB_CHAR);}; - function testRender(results) { - for (var i = results.length; i--; ) { - var parent = dom.createElement("div"); - textLayer.$renderLine(parent, i); - - assert.equal(parent.innerHTML, results[i]); - } - } - - this.session.setValue(" \n\t\tf\n "); - testRender([ - "" + SPACE(4) + "" + SPACE(2), - "" + SPACE(4) + "" + SPACE(4) + "f", - SPACE(3) - ]); - - this.textLayer.setShowInvisibles(true); - testRender([ - "" + DOT(4) + "" + DOT(2) + "" + EOL, - "" + TAB(4) + "" + TAB(4) + "f" + EOL - ]); - - this.textLayer.setDisplayIndentGuides(false); - testRender([ - "" + DOT(6) + "" + EOL, - "" + TAB(4) + "" + TAB(4) + "f" + EOL - ]); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/lib/app_config.js b/lib/ace/lib/app_config.js deleted file mode 100644 index c674a8b4258..00000000000 --- a/lib/ace/lib/app_config.js +++ /dev/null @@ -1,160 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"no use strict"; - -var oop = require("./oop"); -var EventEmitter = require("./event_emitter").EventEmitter; - -var optionsProvider = { - setOptions: function(optList) { - Object.keys(optList).forEach(function(key) { - this.setOption(key, optList[key]); - }, this); - }, - getOptions: function(optionNames) { - var result = {}; - if (!optionNames) { - var options = this.$options; - optionNames = Object.keys(options).filter(function(key) { - return !options[key].hidden; - }); - } else if (!Array.isArray(optionNames)) { - result = optionNames; - optionNames = Object.keys(result); - } - optionNames.forEach(function(key) { - result[key] = this.getOption(key); - }, this); - return result; - }, - setOption: function(name, value) { - if (this["$" + name] === value) - return; - var opt = this.$options[name]; - if (!opt) { - return warn('misspelled option "' + name + '"'); - } - if (opt.forwardTo) - return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value); - - if (!opt.handlesSet) - this["$" + name] = value; - if (opt && opt.set) - opt.set.call(this, value); - }, - getOption: function(name) { - var opt = this.$options[name]; - if (!opt) { - return warn('misspelled option "' + name + '"'); - } - if (opt.forwardTo) - return this[opt.forwardTo] && this[opt.forwardTo].getOption(name); - return opt && opt.get ? opt.get.call(this) : this["$" + name]; - } -}; - -function warn(message) { - if (typeof console != "undefined" && console.warn) - console.warn.apply(console, arguments); -} - -function reportError(msg, data) { - var e = new Error(msg); - e.data = data; - if (typeof console == "object" && console.error) - console.error(e); - setTimeout(function() { throw e; }); -} - -var AppConfig = function() { - this.$defaultOptions = {}; -}; - -(function() { - // module loading - oop.implement(this, EventEmitter); - /* - * option {name, value, initialValue, setterName, set, get } - */ - this.defineOptions = function(obj, path, options) { - if (!obj.$options) - this.$defaultOptions[path] = obj.$options = {}; - - Object.keys(options).forEach(function(key) { - var opt = options[key]; - if (typeof opt == "string") - opt = {forwardTo: opt}; - - opt.name || (opt.name = key); - obj.$options[opt.name] = opt; - if ("initialValue" in opt) - obj["$" + opt.name] = opt.initialValue; - }); - - // implement option provider interface - oop.implement(obj, optionsProvider); - - return this; - }; - - this.resetOptions = function(obj) { - Object.keys(obj.$options).forEach(function(key) { - var opt = obj.$options[key]; - if ("value" in opt) - obj.setOption(key, opt.value); - }); - }; - - this.setDefaultValue = function(path, name, value) { - var opts = this.$defaultOptions[path] || (this.$defaultOptions[path] = {}); - if (opts[name]) { - if (opts.forwardTo) - this.setDefaultValue(opts.forwardTo, name, value); - else - opts[name].value = value; - } - }; - - this.setDefaultValues = function(path, optionHash) { - Object.keys(optionHash).forEach(function(key) { - this.setDefaultValue(path, key, optionHash[key]); - }, this); - }; - - this.warn = warn; - this.reportError = reportError; - -}).call(AppConfig.prototype); - -exports.AppConfig = AppConfig; - -}); diff --git a/lib/ace/lib/dom.js b/lib/ace/lib/dom.js deleted file mode 100644 index 7a14a411468..00000000000 --- a/lib/ace/lib/dom.js +++ /dev/null @@ -1,289 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var useragent = require("./useragent"); -var XHTML_NS = "http://www.w3.org/1999/xhtml"; - -exports.buildDom = function buildDom(arr, parent, refs) { - if (typeof arr == "string" && arr) { - var txt = document.createTextNode(arr); - if (parent) - parent.appendChild(txt); - return txt; - } - - if (!Array.isArray(arr)) - return arr; - if (typeof arr[0] != "string" || !arr[0]) { - var els = []; - for (var i = 0; i < arr.length; i++) { - var ch = buildDom(arr[i], parent, refs); - ch && els.push(ch); - } - return els; - } - - var el = document.createElement(arr[0]); - var options = arr[1]; - var childIndex = 1; - if (options && typeof options == "object" && !Array.isArray(options)) - childIndex = 2; - for (var i = childIndex; i < arr.length; i++) - buildDom(arr[i], el, refs); - if (childIndex == 2) { - Object.keys(options).forEach(function(n) { - var val = options[n]; - if (n === "class") { - el.className = Array.isArray(val) ? val.join(" ") : val; - } else if (typeof val == "function" || n == "value") { - el[n] = val; - } else if (n === "ref") { - if (refs) refs[val] = el; - } else if (val != null) { - el.setAttribute(n, val); - } - }); - } - if (parent) - parent.appendChild(el); - return el; -}; - -exports.getDocumentHead = function(doc) { - if (!doc) - doc = document; - return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement; -}; - -exports.createElement = function(tag, ns) { - return document.createElementNS ? - document.createElementNS(ns || XHTML_NS, tag) : - document.createElement(tag); -}; - -exports.removeChildren = function(element) { - element.innerHTML = ""; -}; - -exports.createTextNode = function(textContent, element) { - var doc = element ? element.ownerDocument : document; - return doc.createTextNode(textContent); -}; - -exports.createFragment = function(element) { - var doc = element ? element.ownerDocument : document; - return doc.createDocumentFragment(); -}; - -exports.hasCssClass = function(el, name) { - var classes = (el.className + "").split(/\s+/g); - return classes.indexOf(name) !== -1; -}; - -/* -* Add a CSS class to the list of classes on the given node -*/ -exports.addCssClass = function(el, name) { - if (!exports.hasCssClass(el, name)) { - el.className += " " + name; - } -}; - -/* -* Remove a CSS class from the list of classes on the given node -*/ -exports.removeCssClass = function(el, name) { - var classes = el.className.split(/\s+/g); - while (true) { - var index = classes.indexOf(name); - if (index == -1) { - break; - } - classes.splice(index, 1); - } - el.className = classes.join(" "); -}; - -exports.toggleCssClass = function(el, name) { - var classes = el.className.split(/\s+/g), add = true; - while (true) { - var index = classes.indexOf(name); - if (index == -1) { - break; - } - add = false; - classes.splice(index, 1); - } - if (add) - classes.push(name); - - el.className = classes.join(" "); - return add; -}; - - -/* - * Add or remove a CSS class from the list of classes on the given node - * depending on the value of include - */ -exports.setCssClass = function(node, className, include) { - if (include) { - exports.addCssClass(node, className); - } else { - exports.removeCssClass(node, className); - } -}; - -exports.hasCssString = function(id, doc) { - var index = 0, sheets; - doc = doc || document; - if ((sheets = doc.querySelectorAll("style"))) { - while (index < sheets.length) - if (sheets[index++].id === id) - return true; - } -}; - -exports.importCssString = function importCssString(cssText, id, container) { - var root = container && container.getRootNode - ? container.getRootNode() - : container || document; - - var doc = root.ownerDocument || root; - - // If style is already imported return immediately. - if (id && exports.hasCssString(id, root)) - return null; - - if (id) - cssText += "\n/*# sourceURL=ace/css/" + id + " */"; - - var style = exports.createElement("style"); - style.appendChild(doc.createTextNode(cssText)); - if (id) - style.id = id; - - if (root == doc) - root = exports.getDocumentHead(doc); - root.insertBefore(style, root.firstChild); -}; - -exports.importCssStylsheet = function(uri, doc) { - exports.buildDom(["link", {rel: "stylesheet", href: uri}], exports.getDocumentHead(doc)); -}; -exports.scrollbarWidth = function(document) { - var inner = exports.createElement("ace_inner"); - inner.style.width = "100%"; - inner.style.minWidth = "0px"; - inner.style.height = "200px"; - inner.style.display = "block"; - - var outer = exports.createElement("ace_outer"); - var style = outer.style; - - style.position = "absolute"; - style.left = "-10000px"; - style.overflow = "hidden"; - style.width = "200px"; - style.minWidth = "0px"; - style.height = "150px"; - style.display = "block"; - - outer.appendChild(inner); - - var body = document.documentElement; - body.appendChild(outer); - - var noScrollbar = inner.offsetWidth; - - style.overflow = "scroll"; - var withScrollbar = inner.offsetWidth; - - if (noScrollbar == withScrollbar) { - withScrollbar = outer.clientWidth; - } - - body.removeChild(outer); - - return noScrollbar-withScrollbar; -}; - -if (typeof document == "undefined") { - exports.importCssString = function() {}; -} - -exports.computedStyle = function(element, style) { - return window.getComputedStyle(element, "") || {}; -}; - -exports.setStyle = function(styles, property, value) { - if (styles[property] !== value) { - //console.log("set style", property, styles[property], value); - styles[property] = value; - } -}; - -exports.HAS_CSS_ANIMATION = false; -if (typeof document !== "undefined") { - var div = document.createElement("div"); - if (typeof div.style.animationName !== "undefined") { - exports.HAS_CSS_ANIMATION = true; - } -} - -exports.HAS_CSS_TRANSFORMS = false; -exports.HI_DPI = useragent.isWin - ? typeof window !== "undefined" && window.devicePixelRatio >= 1.5 - : true; - -if (exports.HI_DPI && typeof document !== "undefined") { - // detect CSS transformation support - var div = document.createElement("div"); - if (div.style.transform !== undefined) - exports.HAS_CSS_TRANSFORMS = true; - div = null; - -} - -if (exports.HAS_CSS_TRANSFORMS) { - exports.translate = function(element, tx, ty) { - element.style.transform = "translate(" + Math.round(tx) + "px, " + Math.round(ty) +"px)"; - }; -} else { - exports.translate = function(element, tx, ty) { - element.style.top = Math.round(ty) + "px"; - element.style.left = Math.round(tx) + "px"; - }; -} - -}); diff --git a/lib/ace/lib/es5-shim.js b/lib/ace/lib/es5-shim.js deleted file mode 100644 index 217bdc61624..00000000000 --- a/lib/ace/lib/es5-shim.js +++ /dev/null @@ -1,1062 +0,0 @@ -// https://github.com/kriskowal/es5-shim -// Copyright 2009-2012 by contributors, MIT License - -define(function(require, exports, module) { - -/* - * Brings an environment as close to ECMAScript 5 compliance - * as is possible with the facilities of erstwhile engines. - * - * Annotated ES5: http://es5.github.com/ (specific links below) - * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf - * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ - */ - -// -// Function -// ======== -// - -// ES-5 15.3.4.5 -// http://es5.github.com/#x15.3.4.5 - -function Empty() {} - -if (!Function.prototype.bind) { - Function.prototype.bind = function bind(that) { // .length is 1 - // 1. Let Target be the this value. - var target = this; - // 2. If IsCallable(Target) is false, throw a TypeError exception. - if (typeof target != "function") { - throw new TypeError("Function.prototype.bind called on incompatible " + target); - } - // 3. Let A be a new (possibly empty) internal list of all of the - // argument values provided after thisArg (arg1, arg2 etc), in order. - // XXX slicedArgs will stand in for "A" if used - var args = slice.call(arguments, 1); // for normal call - // 4. Let F be a new native ECMAScript object. - // 11. Set the [[Prototype]] internal property of F to the standard - // built-in Function prototype object as specified in 15.3.3.1. - // 12. Set the [[Call]] internal property of F as described in - // 15.3.4.5.1. - // 13. Set the [[Construct]] internal property of F as described in - // 15.3.4.5.2. - // 14. Set the [[HasInstance]] internal property of F as described in - // 15.3.4.5.3. - var bound = function () { - - if (this instanceof bound) { - // 15.3.4.5.2 [[Construct]] - // When the [[Construct]] internal method of a function object, - // F that was created using the bind function is called with a - // list of arguments ExtraArgs, the following steps are taken: - // 1. Let target be the value of F's [[TargetFunction]] - // internal property. - // 2. If target has no [[Construct]] internal method, a - // TypeError exception is thrown. - // 3. Let boundArgs be the value of F's [[BoundArgs]] internal - // property. - // 4. Let args be a new list containing the same values as the - // list boundArgs in the same order followed by the same - // values as the list ExtraArgs in the same order. - // 5. Return the result of calling the [[Construct]] internal - // method of target providing args as the arguments. - - var result = target.apply( - this, - args.concat(slice.call(arguments)) - ); - if (Object(result) === result) { - return result; - } - return this; - - } else { - // 15.3.4.5.1 [[Call]] - // When the [[Call]] internal method of a function object, F, - // which was created using the bind function is called with a - // this value and a list of arguments ExtraArgs, the following - // steps are taken: - // 1. Let boundArgs be the value of F's [[BoundArgs]] internal - // property. - // 2. Let boundThis be the value of F's [[BoundThis]] internal - // property. - // 3. Let target be the value of F's [[TargetFunction]] internal - // property. - // 4. Let args be a new list containing the same values as the - // list boundArgs in the same order followed by the same - // values as the list ExtraArgs in the same order. - // 5. Return the result of calling the [[Call]] internal method - // of target providing boundThis as the this value and - // providing args as the arguments. - - // equiv: target.call(this, ...boundArgs, ...args) - return target.apply( - that, - args.concat(slice.call(arguments)) - ); - - } - - }; - if(target.prototype) { - Empty.prototype = target.prototype; - bound.prototype = new Empty(); - // Clean up dangling references. - Empty.prototype = null; - } - // XXX bound.length is never writable, so don't even try - // - // 15. If the [[Class]] internal property of Target is "Function", then - // a. Let L be the length property of Target minus the length of A. - // b. Set the length own property of F to either 0 or L, whichever is - // larger. - // 16. Else set the length own property of F to 0. - // 17. Set the attributes of the length own property of F to the values - // specified in 15.3.5.1. - - // TODO - // 18. Set the [[Extensible]] internal property of F to true. - - // TODO - // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). - // 20. Call the [[DefineOwnProperty]] internal method of F with - // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: - // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and - // false. - // 21. Call the [[DefineOwnProperty]] internal method of F with - // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, - // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, - // and false. - - // TODO - // NOTE Function objects created using Function.prototype.bind do not - // have a prototype property or the [[Code]], [[FormalParameters]], and - // [[Scope]] internal properties. - // XXX can't delete prototype in pure-js. - - // 22. Return F. - return bound; - }; -} - -// Shortcut to an often accessed properties, in order to avoid multiple -// dereference that costs universally. -// _Please note: Shortcuts are defined after `Function.prototype.bind` as we -// us it in defining shortcuts. -var call = Function.prototype.call; -var prototypeOfArray = Array.prototype; -var prototypeOfObject = Object.prototype; -var slice = prototypeOfArray.slice; -// Having a toString local variable name breaks in Opera so use _toString. -var _toString = call.bind(prototypeOfObject.toString); -var owns = call.bind(prototypeOfObject.hasOwnProperty); - -// If JS engine supports accessors creating shortcuts. -var defineGetter; -var defineSetter; -var lookupGetter; -var lookupSetter; -var supportsAccessors; -if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { - defineGetter = call.bind(prototypeOfObject.__defineGetter__); - defineSetter = call.bind(prototypeOfObject.__defineSetter__); - lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); - lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); -} - -// -// Array -// ===== -// - -// ES5 15.4.4.12 -// http://es5.github.com/#x15.4.4.12 -// Default value for second param -// [bugfix, ielt9, old browsers] -// IE < 9 bug: [1,2].splice(0).join("") == "" but should be "12" -if ([1,2].splice(0).length != 2) { - if(function() { // test IE < 9 to splice bug - see issue #138 - function makeArray(l) { - var a = new Array(l+2); - a[0] = a[1] = 0; - return a; - } - var array = [], lengthBefore; - - array.splice.apply(array, makeArray(20)); - array.splice.apply(array, makeArray(26)); - - lengthBefore = array.length; //46 - array.splice(5, 0, "XXX"); // add one element - - lengthBefore + 1 == array.length - - if (lengthBefore + 1 == array.length) { - return true;// has right splice implementation without bugs - } - // else { - // IE8 bug - // } - }()) {//IE 6/7 - var array_splice = Array.prototype.splice; - Array.prototype.splice = function(start, deleteCount) { - if (!arguments.length) { - return []; - } else { - return array_splice.apply(this, [ - start === void 0 ? 0 : start, - deleteCount === void 0 ? (this.length - start) : deleteCount - ].concat(slice.call(arguments, 2))) - } - }; - } else {//IE8 - // taken from http://docs.sencha.com/ext-js/4-1/source/Array2.html - Array.prototype.splice = function(pos, removeCount){ - var length = this.length; - if (pos > 0) { - if (pos > length) - pos = length; - } else if (pos == void 0) { - pos = 0; - } else if (pos < 0) { - pos = Math.max(length + pos, 0); - } - - if (!(pos+removeCount < length)) - removeCount = length - pos; - - var removed = this.slice(pos, pos+removeCount); - var insert = slice.call(arguments, 2); - var add = insert.length; - - // we try to use Array.push when we can for efficiency... - if (pos === length) { - if (add) { - this.push.apply(this, insert); - } - } else { - var remove = Math.min(removeCount, length - pos); - var tailOldPos = pos + remove; - var tailNewPos = tailOldPos + add - remove; - var tailCount = length - tailOldPos; - var lengthAfterRemove = length - remove; - - if (tailNewPos < tailOldPos) { // case A - for (var i = 0; i < tailCount; ++i) { - this[tailNewPos+i] = this[tailOldPos+i]; - } - } else if (tailNewPos > tailOldPos) { // case B - for (i = tailCount; i--; ) { - this[tailNewPos+i] = this[tailOldPos+i]; - } - } // else, add == remove (nothing to do) - - if (add && pos === lengthAfterRemove) { - this.length = lengthAfterRemove; // truncate array - this.push.apply(this, insert); - } else { - this.length = lengthAfterRemove + add; // reserves space - for (i = 0; i < add; ++i) { - this[pos+i] = insert[i]; - } - } - } - return removed; - }; - } -} - -// ES5 15.4.3.2 -// http://es5.github.com/#x15.4.3.2 -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray -if (!Array.isArray) { - Array.isArray = function isArray(obj) { - return _toString(obj) == "[object Array]"; - }; -} - -// The IsCallable() check in the Array functions -// has been replaced with a strict check on the -// internal class of the object to trap cases where -// the provided function was actually a regular -// expression literal, which in V8 and -// JavaScriptCore is a typeof "function". Only in -// V8 are regular expression literals permitted as -// reduce parameters, so it is desirable in the -// general case for the shim to match the more -// strict and common behavior of rejecting regular -// expressions. - -// ES5 15.4.4.18 -// http://es5.github.com/#x15.4.4.18 -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach - -// Check failure of by-index access of string characters (IE < 9) -// and failure of `0 in boxedString` (Rhino) -var boxedString = Object("a"), - splitString = boxedString[0] != "a" || !(0 in boxedString); - -if (!Array.prototype.forEach) { - Array.prototype.forEach = function forEach(fun /*, thisp*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - thisp = arguments[1], - i = -1, - length = self.length >>> 0; - - // If no callback function or if callback is not a callable function - if (_toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message - } - - while (++i < length) { - if (i in self) { - // Invoke the callback function with call, passing arguments: - // context, property value, property key, thisArg object - // context - fun.call(thisp, self[i], i, object); - } - } - }; -} - -// ES5 15.4.4.19 -// http://es5.github.com/#x15.4.4.19 -// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map -if (!Array.prototype.map) { - Array.prototype.map = function map(fun /*, thisp*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - result = Array(length), - thisp = arguments[1]; - - // If no callback function or if callback is not a callable function - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self) - result[i] = fun.call(thisp, self[i], i, object); - } - return result; - }; -} - -// ES5 15.4.4.20 -// http://es5.github.com/#x15.4.4.20 -// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter -if (!Array.prototype.filter) { - Array.prototype.filter = function filter(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - result = [], - value, - thisp = arguments[1]; - - // If no callback function or if callback is not a callable function - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self) { - value = self[i]; - if (fun.call(thisp, value, i, object)) { - result.push(value); - } - } - } - return result; - }; -} - -// ES5 15.4.4.16 -// http://es5.github.com/#x15.4.4.16 -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every -if (!Array.prototype.every) { - Array.prototype.every = function every(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - thisp = arguments[1]; - - // If no callback function or if callback is not a callable function - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self && !fun.call(thisp, self[i], i, object)) { - return false; - } - } - return true; - }; -} - -// ES5 15.4.4.17 -// http://es5.github.com/#x15.4.4.17 -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some -if (!Array.prototype.some) { - Array.prototype.some = function some(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - thisp = arguments[1]; - - // If no callback function or if callback is not a callable function - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self && fun.call(thisp, self[i], i, object)) { - return true; - } - } - return false; - }; -} - -// ES5 15.4.4.21 -// http://es5.github.com/#x15.4.4.21 -// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce -if (!Array.prototype.reduce) { - Array.prototype.reduce = function reduce(fun /*, initial*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0; - - // If no callback function or if callback is not a callable function - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - // no value to return if no initial value and an empty array - if (!length && arguments.length == 1) { - throw new TypeError("reduce of empty array with no initial value"); - } - - var i = 0; - var result; - if (arguments.length >= 2) { - result = arguments[1]; - } else { - do { - if (i in self) { - result = self[i++]; - break; - } - - // if array contains no values, no initial value to return - if (++i >= length) { - throw new TypeError("reduce of empty array with no initial value"); - } - } while (true); - } - - for (; i < length; i++) { - if (i in self) { - result = fun.call(void 0, result, self[i], i, object); - } - } - - return result; - }; -} - -// ES5 15.4.4.22 -// http://es5.github.com/#x15.4.4.22 -// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight -if (!Array.prototype.reduceRight) { - Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0; - - // If no callback function or if callback is not a callable function - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - // no value to return if no initial value, empty array - if (!length && arguments.length == 1) { - throw new TypeError("reduceRight of empty array with no initial value"); - } - - var result, i = length - 1; - if (arguments.length >= 2) { - result = arguments[1]; - } else { - do { - if (i in self) { - result = self[i--]; - break; - } - - // if array contains no values, no initial value to return - if (--i < 0) { - throw new TypeError("reduceRight of empty array with no initial value"); - } - } while (true); - } - - do { - if (i in this) { - result = fun.call(void 0, result, self[i], i, object); - } - } while (i--); - - return result; - }; -} - -// ES5 15.4.4.14 -// http://es5.github.com/#x15.4.4.14 -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf -if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { - Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { - var self = splitString && _toString(this) == "[object String]" ? - this.split("") : - toObject(this), - length = self.length >>> 0; - - if (!length) { - return -1; - } - - var i = 0; - if (arguments.length > 1) { - i = toInteger(arguments[1]); - } - - // handle negative indices - i = i >= 0 ? i : Math.max(0, length + i); - for (; i < length; i++) { - if (i in self && self[i] === sought) { - return i; - } - } - return -1; - }; -} - -// ES5 15.4.4.15 -// http://es5.github.com/#x15.4.4.15 -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf -if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { - Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { - var self = splitString && _toString(this) == "[object String]" ? - this.split("") : - toObject(this), - length = self.length >>> 0; - - if (!length) { - return -1; - } - var i = length - 1; - if (arguments.length > 1) { - i = Math.min(i, toInteger(arguments[1])); - } - // handle negative indices - i = i >= 0 ? i : length - Math.abs(i); - for (; i >= 0; i--) { - if (i in self && sought === self[i]) { - return i; - } - } - return -1; - }; -} - -// -// Object -// ====== -// - -// ES5 15.2.3.2 -// http://es5.github.com/#x15.2.3.2 -if (!Object.getPrototypeOf) { - // https://github.com/kriskowal/es5-shim/issues#issue/2 - // http://ejohn.org/blog/objectgetprototypeof/ - // recommended by fschaefer on github - Object.getPrototypeOf = function getPrototypeOf(object) { - return object.__proto__ || ( - object.constructor ? - object.constructor.prototype : - prototypeOfObject - ); - }; -} - -// ES5 15.2.3.3 -// http://es5.github.com/#x15.2.3.3 -if (!Object.getOwnPropertyDescriptor) { - var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " + - "non-object: "; - Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { - if ((typeof object != "object" && typeof object != "function") || object === null) - throw new TypeError(ERR_NON_OBJECT + object); - // If object does not owns property return undefined immediately. - if (!owns(object, property)) - return; - - var descriptor, getter, setter; - - // If object has a property then it's for sure both `enumerable` and - // `configurable`. - descriptor = { enumerable: true, configurable: true }; - - // If JS engine supports accessor properties then property may be a - // getter or setter. - if (supportsAccessors) { - // Unfortunately `__lookupGetter__` will return a getter even - // if object has own non getter property along with a same named - // inherited getter. To avoid misbehavior we temporary remove - // `__proto__` so that `__lookupGetter__` will return getter only - // if it's owned by an object. - var prototype = object.__proto__; - object.__proto__ = prototypeOfObject; - - var getter = lookupGetter(object, property); - var setter = lookupSetter(object, property); - - // Once we have getter and setter we can put values back. - object.__proto__ = prototype; - - if (getter || setter) { - if (getter) descriptor.get = getter; - if (setter) descriptor.set = setter; - - // If it was accessor property we're done and return here - // in order to avoid adding `value` to the descriptor. - return descriptor; - } - } - - // If we got this far we know that object has an own property that is - // not an accessor so we set it as a value and return descriptor. - descriptor.value = object[property]; - return descriptor; - }; -} - -// ES5 15.2.3.4 -// http://es5.github.com/#x15.2.3.4 -if (!Object.getOwnPropertyNames) { - Object.getOwnPropertyNames = function getOwnPropertyNames(object) { - return Object.keys(object); - }; -} - -// ES5 15.2.3.5 -// http://es5.github.com/#x15.2.3.5 -if (!Object.create) { - var createEmpty; - if (Object.prototype.__proto__ === null) { - createEmpty = function () { - return { "__proto__": null }; - }; - } else { - // In old IE __proto__ can't be used to manually set `null` - createEmpty = function () { - var empty = {}; - for (var i in empty) - empty[i] = null; - empty.constructor = - empty.hasOwnProperty = - empty.propertyIsEnumerable = - empty.isPrototypeOf = - empty.toLocaleString = - empty.toString = - empty.valueOf = - empty.__proto__ = null; - return empty; - } - } - - Object.create = function create(prototype, properties) { - var object; - if (prototype === null) { - object = createEmpty(); - } else { - if (typeof prototype != "object") - throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); - var Type = function () {}; - Type.prototype = prototype; - object = new Type(); - // IE has no built-in implementation of `Object.getPrototypeOf` - // neither `__proto__`, but this manually setting `__proto__` will - // guarantee that `Object.getPrototypeOf` will work as expected with - // objects created using `Object.create` - object.__proto__ = prototype; - } - if (properties !== void 0) - Object.defineProperties(object, properties); - return object; - }; -} - -// ES5 15.2.3.6 -// http://es5.github.com/#x15.2.3.6 - -// Patch for WebKit and IE8 standard mode -// Designed by hax -// related issue: https://github.com/kriskowal/es5-shim/issues#issue/5 -// IE8 Reference: -// http://msdn.microsoft.com/en-us/library/dd282900.aspx -// http://msdn.microsoft.com/en-us/library/dd229916.aspx -// WebKit Bugs: -// https://bugs.webkit.org/show_bug.cgi?id=36423 - -function doesDefinePropertyWork(object) { - try { - Object.defineProperty(object, "sentinel", {}); - return "sentinel" in object; - } catch (exception) { - // returns falsy - } -} - -// check whether defineProperty works if it's given. Otherwise, -// shim partially. -if (Object.defineProperty) { - var definePropertyWorksOnObject = doesDefinePropertyWork({}); - var definePropertyWorksOnDom = typeof document == "undefined" || - doesDefinePropertyWork(document.createElement("div")); - if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { - var definePropertyFallback = Object.defineProperty; - } -} - -if (!Object.defineProperty || definePropertyFallback) { - var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; - var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " - var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + - "on this javascript engine"; - - Object.defineProperty = function defineProperty(object, property, descriptor) { - if ((typeof object != "object" && typeof object != "function") || object === null) - throw new TypeError(ERR_NON_OBJECT_TARGET + object); - if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) - throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); - - // make a valiant attempt to use the real defineProperty - // for I8's DOM elements. - if (definePropertyFallback) { - try { - return definePropertyFallback.call(Object, object, property, descriptor); - } catch (exception) { - // try the shim if the real one doesn't work - } - } - - // If it's a data property. - if (owns(descriptor, "value")) { - // fail silently if "writable", "enumerable", or "configurable" - // are requested but not supported - /* - // alternate approach: - if ( // can't implement these features; allow false but not true - !(owns(descriptor, "writable") ? descriptor.writable : true) || - !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) || - !(owns(descriptor, "configurable") ? descriptor.configurable : true) - ) - throw new RangeError( - "This implementation of Object.defineProperty does not " + - "support configurable, enumerable, or writable." - ); - */ - - if (supportsAccessors && (lookupGetter(object, property) || - lookupSetter(object, property))) - { - // As accessors are supported only on engines implementing - // `__proto__` we can safely override `__proto__` while defining - // a property to make sure that we don't hit an inherited - // accessor. - var prototype = object.__proto__; - object.__proto__ = prototypeOfObject; - // Deleting a property anyway since getter / setter may be - // defined on object itself. - delete object[property]; - object[property] = descriptor.value; - // Setting original `__proto__` back now. - object.__proto__ = prototype; - } else { - object[property] = descriptor.value; - } - } else { - if (!supportsAccessors) - throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); - // If we got that far then getters and setters can be defined !! - if (owns(descriptor, "get")) - defineGetter(object, property, descriptor.get); - if (owns(descriptor, "set")) - defineSetter(object, property, descriptor.set); - } - - return object; - }; -} - -// ES5 15.2.3.7 -// http://es5.github.com/#x15.2.3.7 -if (!Object.defineProperties) { - Object.defineProperties = function defineProperties(object, properties) { - for (var property in properties) { - if (owns(properties, property)) - Object.defineProperty(object, property, properties[property]); - } - return object; - }; -} - -// ES5 15.2.3.8 -// http://es5.github.com/#x15.2.3.8 -if (!Object.seal) { - Object.seal = function seal(object) { - // this is misleading and breaks feature-detection, but - // allows "securable" code to "gracefully" degrade to working - // but insecure code. - return object; - }; -} - -// ES5 15.2.3.9 -// http://es5.github.com/#x15.2.3.9 -if (!Object.freeze) { - Object.freeze = function freeze(object) { - // this is misleading and breaks feature-detection, but - // allows "securable" code to "gracefully" degrade to working - // but insecure code. - return object; - }; -} - -// detect a Rhino bug and patch it -try { - Object.freeze(function () {}); -} catch (exception) { - Object.freeze = (function freeze(freezeObject) { - return function freeze(object) { - if (typeof object == "function") { - return object; - } else { - return freezeObject(object); - } - }; - })(Object.freeze); -} - -// ES5 15.2.3.10 -// http://es5.github.com/#x15.2.3.10 -if (!Object.preventExtensions) { - Object.preventExtensions = function preventExtensions(object) { - // this is misleading and breaks feature-detection, but - // allows "securable" code to "gracefully" degrade to working - // but insecure code. - return object; - }; -} - -// ES5 15.2.3.11 -// http://es5.github.com/#x15.2.3.11 -if (!Object.isSealed) { - Object.isSealed = function isSealed(object) { - return false; - }; -} - -// ES5 15.2.3.12 -// http://es5.github.com/#x15.2.3.12 -if (!Object.isFrozen) { - Object.isFrozen = function isFrozen(object) { - return false; - }; -} - -// ES5 15.2.3.13 -// http://es5.github.com/#x15.2.3.13 -if (!Object.isExtensible) { - Object.isExtensible = function isExtensible(object) { - // 1. If Type(O) is not Object throw a TypeError exception. - if (Object(object) === object) { - throw new TypeError(); // TODO message - } - // 2. Return the Boolean value of the [[Extensible]] internal property of O. - var name = ''; - while (owns(object, name)) { - name += '?'; - } - object[name] = true; - var returnValue = owns(object, name); - delete object[name]; - return returnValue; - }; -} - -// ES5 15.2.3.14 -// http://es5.github.com/#x15.2.3.14 -if (!Object.keys) { - // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation - var hasDontEnumBug = true, - dontEnums = [ - "toString", - "toLocaleString", - "valueOf", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "constructor" - ], - dontEnumsLength = dontEnums.length; - - for (var key in {"toString": null}) { - hasDontEnumBug = false; - } - - Object.keys = function keys(object) { - - if ( - (typeof object != "object" && typeof object != "function") || - object === null - ) { - throw new TypeError("Object.keys called on a non-object"); - } - - var keys = []; - for (var name in object) { - if (owns(object, name)) { - keys.push(name); - } - } - - if (hasDontEnumBug) { - for (var i = 0, ii = dontEnumsLength; i < ii; i++) { - var dontEnum = dontEnums[i]; - if (owns(object, dontEnum)) { - keys.push(dontEnum); - } - } - } - return keys; - }; - -} - -// -// most of es5-shim Date section is removed since ace doesn't need it, it is too intrusive and it causes problems for users -// ==== -// - -// ES5 15.9.4.4 -// http://es5.github.com/#x15.9.4.4 -if (!Date.now) { - Date.now = function now() { - return new Date().getTime(); - }; -} - - -// -// String -// ====== -// - -// ES5 15.5.4.20 -// http://es5.github.com/#x15.5.4.20 -var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + - "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + - "\u2029\uFEFF"; -if (!String.prototype.trim || ws.trim()) { - // http://blog.stevenlevithan.com/archives/faster-trim-javascript - // http://perfectionkills.com/whitespace-deviations/ - ws = "[" + ws + "]"; - var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), - trimEndRegexp = new RegExp(ws + ws + "*$"); - String.prototype.trim = function trim() { - return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); - }; -} - -// -// Util -// ====== -// - -// ES5 9.4 -// http://es5.github.com/#x9.4 -// http://jsperf.com/to-integer - -function toInteger(n) { - n = +n; - if (n !== n) { // isNaN - n = 0; - } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - return n; -} - -function isPrimitive(input) { - var type = typeof input; - return ( - input === null || - type === "undefined" || - type === "boolean" || - type === "number" || - type === "string" - ); -} - -function toPrimitive(input) { - var val, valueOf, toString; - if (isPrimitive(input)) { - return input; - } - valueOf = input.valueOf; - if (typeof valueOf === "function") { - val = valueOf.call(input); - if (isPrimitive(val)) { - return val; - } - } - toString = input.toString; - if (typeof toString === "function") { - val = toString.call(input); - if (isPrimitive(val)) { - return val; - } - } - throw new TypeError(); -} - -// ES5 9.9 -// http://es5.github.com/#x9.9 -var toObject = function (o) { - if (o == null) { // this matches both null and undefined - throw new TypeError("can't convert "+o+" to object"); - } - return Object(o); -}; - -}); diff --git a/lib/ace/lib/event.js b/lib/ace/lib/event.js deleted file mode 100644 index 2b2d52f5474..00000000000 --- a/lib/ace/lib/event.js +++ /dev/null @@ -1,423 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var keys = require("./keys"); -var useragent = require("./useragent"); - -var pressedKeys = null; -var ts = 0; - -exports.addListener = function(elem, type, callback) { - if (elem.addEventListener) { - return elem.addEventListener(type, callback, false); - } - if (elem.attachEvent) { - var wrapper = function() { - callback.call(elem, window.event); - }; - callback._wrapper = wrapper; - elem.attachEvent("on" + type, wrapper); - } -}; - -exports.removeListener = function(elem, type, callback) { - if (elem.removeEventListener) { - return elem.removeEventListener(type, callback, false); - } - if (elem.detachEvent) { - elem.detachEvent("on" + type, callback._wrapper || callback); - } -}; - -/* -* Prevents propagation and clobbers the default action of the passed event -*/ -exports.stopEvent = function(e) { - exports.stopPropagation(e); - exports.preventDefault(e); - return false; -}; - -exports.stopPropagation = function(e) { - if (e.stopPropagation) - e.stopPropagation(); - else - e.cancelBubble = true; -}; - -exports.preventDefault = function(e) { - if (e.preventDefault) - e.preventDefault(); - else - e.returnValue = false; -}; - -/* - * @return {Number} 0 for left button, 1 for middle button, 2 for right button - */ -exports.getButton = function(e) { - if (e.type == "dblclick") - return 0; - if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey))) - return 2; - - // DOM Event - if (e.preventDefault) { - return e.button; - } - // old IE - else { - return {1:0, 2:2, 4:1}[e.button]; - } -}; - -exports.capture = function(el, eventHandler, releaseCaptureHandler) { - function onMouseUp(e) { - eventHandler && eventHandler(e); - releaseCaptureHandler && releaseCaptureHandler(e); - - exports.removeListener(document, "mousemove", eventHandler, true); - exports.removeListener(document, "mouseup", onMouseUp, true); - exports.removeListener(document, "dragstart", onMouseUp, true); - } - - exports.addListener(document, "mousemove", eventHandler, true); - exports.addListener(document, "mouseup", onMouseUp, true); - exports.addListener(document, "dragstart", onMouseUp, true); - - return onMouseUp; -}; - -exports.addTouchMoveListener = function (el, callback) { - var startx, starty; - exports.addListener(el, "touchstart", function (e) { - var touches = e.touches; - var touchObj = touches[0]; - startx = touchObj.clientX; - starty = touchObj.clientY; - }); - exports.addListener(el, "touchmove", function (e) { - var touches = e.touches; - if (touches.length > 1) return; - - var touchObj = touches[0]; - - e.wheelX = startx - touchObj.clientX; - e.wheelY = starty - touchObj.clientY; - - startx = touchObj.clientX; - starty = touchObj.clientY; - - callback(e); - }); -}; - -exports.addMouseWheelListener = function(el, callback) { - if ("onmousewheel" in el) { - exports.addListener(el, "mousewheel", function(e) { - var factor = 8; - if (e.wheelDeltaX !== undefined) { - e.wheelX = -e.wheelDeltaX / factor; - e.wheelY = -e.wheelDeltaY / factor; - } else { - e.wheelX = 0; - e.wheelY = -e.wheelDelta / factor; - } - callback(e); - }); - } else if ("onwheel" in el) { - exports.addListener(el, "wheel", function(e) { - var factor = 0.35; - switch (e.deltaMode) { - case e.DOM_DELTA_PIXEL: - e.wheelX = e.deltaX * factor || 0; - e.wheelY = e.deltaY * factor || 0; - break; - case e.DOM_DELTA_LINE: - case e.DOM_DELTA_PAGE: - e.wheelX = (e.deltaX || 0) * 5; - e.wheelY = (e.deltaY || 0) * 5; - break; - } - - callback(e); - }); - } else { - exports.addListener(el, "DOMMouseScroll", function(e) { - if (e.axis && e.axis == e.HORIZONTAL_AXIS) { - e.wheelX = (e.detail || 0) * 5; - e.wheelY = 0; - } else { - e.wheelX = 0; - e.wheelY = (e.detail || 0) * 5; - } - callback(e); - }); - } -}; - -exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName) { - var clicks = 0; - var startX, startY, timer; - var eventNames = { - 2: "dblclick", - 3: "tripleclick", - 4: "quadclick" - }; - - function onMousedown(e) { - if (exports.getButton(e) !== 0) { - clicks = 0; - } else if (e.detail > 1) { - clicks++; - if (clicks > 4) - clicks = 1; - } else { - clicks = 1; - } - if (useragent.isIE) { - var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5; - if (!timer || isNewClick) - clicks = 1; - if (timer) - clearTimeout(timer); - timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600); - - if (clicks == 1) { - startX = e.clientX; - startY = e.clientY; - } - } - - e._clicks = clicks; - - eventHandler[callbackName]("mousedown", e); - - if (clicks > 4) - clicks = 0; - else if (clicks > 1) - return eventHandler[callbackName](eventNames[clicks], e); - } - function onDblclick(e) { - clicks = 2; - if (timer) - clearTimeout(timer); - timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600); - eventHandler[callbackName]("mousedown", e); - eventHandler[callbackName](eventNames[clicks], e); - } - if (!Array.isArray(elements)) - elements = [elements]; - elements.forEach(function(el) { - exports.addListener(el, "mousedown", onMousedown); - if (useragent.isOldIE) - exports.addListener(el, "dblclick", onDblclick); - }); -}; - -var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window) - ? function(e) { - return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0); - } - : function(e) { - return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0); - }; - -exports.getModifierString = function(e) { - return keys.KEY_MODS[getModifierHash(e)]; -}; - -function normalizeCommandKeys(callback, e, keyCode) { - var hashId = getModifierHash(e); - - if (!useragent.isMac && pressedKeys) { - if (e.getModifierState && (e.getModifierState("OS") || e.getModifierState("Win"))) - hashId |= 8; - if (pressedKeys.altGr) { - if ((3 & hashId) != 3) - pressedKeys.altGr = 0; - else - return; - } - if (keyCode === 18 || keyCode === 17) { - var location = "location" in e ? e.location : e.keyLocation; - if (keyCode === 17 && location === 1) { - if (pressedKeys[keyCode] == 1) - ts = e.timeStamp; - } else if (keyCode === 18 && hashId === 3 && location === 2) { - var dt = e.timeStamp - ts; - if (dt < 50) - pressedKeys.altGr = true; - } - } - } - - if (keyCode in keys.MODIFIER_KEYS) { - keyCode = -1; - } - - // keyCode of right command is 93 on mac and 92 on windows. - // keyCode of left command key is 91 - if (hashId & 8 && (keyCode >= 91 && keyCode <= 93)) { - keyCode = -1; - } - - if (!hashId && keyCode === 13) { - var location = "location" in e ? e.location : e.keyLocation; - if (location === 3) { - callback(e, hashId, -keyCode); - if (e.defaultPrevented) - return; - } - } - - if (useragent.isChromeOS && hashId & 8) { - callback(e, hashId, keyCode); - if (e.defaultPrevented) - return; - else - hashId &= ~8; - } - - // If there is no hashId and the keyCode is not a function key, then - // we don't call the callback as we don't handle a command key here - // (it's a normal key/character input). - if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) { - return false; - } - - return callback(e, hashId, keyCode); -} - - -exports.addCommandKeyListener = function(el, callback) { - var addListener = exports.addListener; - if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) { - // Old versions of Gecko aka. Firefox < 4.0 didn't repeat the keydown - // event if the user pressed the key for a longer time. Instead, the - // keydown event was fired once and later on only the keypress event. - // To emulate the 'right' keydown behavior, the keyCode of the initial - // keyDown event is stored and in the following keypress events the - // stores keyCode is used to emulate a keyDown event. - var lastKeyDownKeyCode = null; - addListener(el, "keydown", function(e) { - lastKeyDownKeyCode = e.keyCode; - }); - addListener(el, "keypress", function(e) { - return normalizeCommandKeys(callback, e, lastKeyDownKeyCode); - }); - } else { - var lastDefaultPrevented = null; - - addListener(el, "keydown", function(e) { - pressedKeys[e.keyCode] = (pressedKeys[e.keyCode] || 0) + 1; - var result = normalizeCommandKeys(callback, e, e.keyCode); - lastDefaultPrevented = e.defaultPrevented; - return result; - }); - - addListener(el, "keypress", function(e) { - if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) { - exports.stopEvent(e); - lastDefaultPrevented = null; - } - }); - - addListener(el, "keyup", function(e) { - pressedKeys[e.keyCode] = null; - }); - - if (!pressedKeys) { - resetPressedKeys(); - addListener(window, "focus", resetPressedKeys); - } - } -}; -function resetPressedKeys() { - pressedKeys = Object.create(null); -} - -if (typeof window == "object" && window.postMessage && !useragent.isOldIE) { - var postMessageId = 1; - exports.nextTick = function(callback, win) { - win = win || window; - var messageName = "zero-timeout-message-" + (postMessageId++); - - var listener = function(e) { - if (e.data == messageName) { - exports.stopPropagation(e); - exports.removeListener(win, "message", listener); - callback(); - } - }; - - exports.addListener(win, "message", listener); - win.postMessage(messageName, "*"); - }; -} - -exports.$idleBlocked = false; -exports.onIdle = function(cb, timeout) { - return setTimeout(function handler() { - if (!exports.$idleBlocked) { - cb(); - } else { - setTimeout(handler, 100); - } - }, timeout); -}; - -exports.$idleBlockId = null; -exports.blockIdle = function(delay) { - if (exports.$idleBlockId) - clearTimeout(exports.$idleBlockId); - - exports.$idleBlocked = true; - exports.$idleBlockId = setTimeout(function() { - exports.$idleBlocked = false; - }, delay || 100); -}; - -exports.nextFrame = typeof window == "object" && (window.requestAnimationFrame - || window.mozRequestAnimationFrame - || window.webkitRequestAnimationFrame - || window.msRequestAnimationFrame - || window.oRequestAnimationFrame); - -if (exports.nextFrame) - exports.nextFrame = exports.nextFrame.bind(window); -else - exports.nextFrame = function(callback) { - setTimeout(callback, 17); - }; -}); diff --git a/lib/ace/lib/event_emitter.js b/lib/ace/lib/event_emitter.js deleted file mode 100644 index 6d5c2f0ed2e..00000000000 --- a/lib/ace/lib/event_emitter.js +++ /dev/null @@ -1,154 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var EventEmitter = {}; -var stopPropagation = function() { this.propagationStopped = true; }; -var preventDefault = function() { this.defaultPrevented = true; }; - -EventEmitter._emit = -EventEmitter._dispatchEvent = function(eventName, e) { - this._eventRegistry || (this._eventRegistry = {}); - this._defaultHandlers || (this._defaultHandlers = {}); - - var listeners = this._eventRegistry[eventName] || []; - var defaultHandler = this._defaultHandlers[eventName]; - if (!listeners.length && !defaultHandler) - return; - - if (typeof e != "object" || !e) - e = {}; - - if (!e.type) - e.type = eventName; - if (!e.stopPropagation) - e.stopPropagation = stopPropagation; - if (!e.preventDefault) - e.preventDefault = preventDefault; - - listeners = listeners.slice(); - for (var i=0; i 0) { - if (count & 1) - result += string; - - if (count >>= 1) - string += string; - } - return result; -}; - -var trimBeginRegexp = /^\s\s*/; -var trimEndRegexp = /\s\s*$/; - -exports.stringTrimLeft = function (string) { - return string.replace(trimBeginRegexp, ''); -}; - -exports.stringTrimRight = function (string) { - return string.replace(trimEndRegexp, ''); -}; - -exports.copyObject = function(obj) { - var copy = {}; - for (var key in obj) { - copy[key] = obj[key]; - } - return copy; -}; - -exports.copyArray = function(array){ - var copy = []; - for (var i=0, l=array.length; i - * Provides an augmented, extensible, cross-browser implementation of regular expressions, - * including support for additional syntax, flags, and methods - */ - -define(function(require, exports, module) { -"use strict"; - - //--------------------------------- - // Private variables - //--------------------------------- - - var real = { - exec: RegExp.prototype.exec, - test: RegExp.prototype.test, - match: String.prototype.match, - replace: String.prototype.replace, - split: String.prototype.split - }, - compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups - compliantLastIndexIncrement = function () { - var x = /^/g; - real.test.call(x, ""); - return !x.lastIndex; - }(); - - if (compliantLastIndexIncrement && compliantExecNpcg) - return; - - //--------------------------------- - // Overriden native methods - //--------------------------------- - - // Adds named capture support (with backreferences returned as `result.name`), and fixes two - // cross-browser issues per ES3: - // - Captured values for nonparticipating capturing groups should be returned as `undefined`, - // rather than the empty string. - // - `lastIndex` should not be incremented after zero-length matches. - RegExp.prototype.exec = function (str) { - var match = real.exec.apply(this, arguments), - name, r2; - if ( typeof(str) == 'string' && match) { - // Fix browsers whose `exec` methods don't consistently return `undefined` for - // nonparticipating capturing groups - if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) { - r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", "")); - // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed - // matching due to characters outside the match - real.replace.call(str.slice(match.index), r2, function () { - for (var i = 1; i < arguments.length - 2; i++) { - if (arguments[i] === undefined) - match[i] = undefined; - } - }); - } - // Attach named capture properties - if (this._xregexp && this._xregexp.captureNames) { - for (var i = 1; i < match.length; i++) { - name = this._xregexp.captureNames[i - 1]; - if (name) - match[name] = match[i]; - } - } - // Fix browsers that increment `lastIndex` after zero-length matches - if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index)) - this.lastIndex--; - } - return match; - }; - - // Don't override `test` if it won't change anything - if (!compliantLastIndexIncrement) { - // Fix browser bug in native method - RegExp.prototype.test = function (str) { - // Use the native `exec` to skip some processing overhead, even though the overriden - // `exec` would take care of the `lastIndex` fix - var match = real.exec.call(this, str); - // Fix browsers that increment `lastIndex` after zero-length matches - if (match && this.global && !match[0].length && (this.lastIndex > match.index)) - this.lastIndex--; - return !!match; - }; - } - - //--------------------------------- - // Private helper functions - //--------------------------------- - - function getNativeFlags (regex) { - return (regex.global ? "g" : "") + - (regex.ignoreCase ? "i" : "") + - (regex.multiline ? "m" : "") + - (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3 - (regex.sticky ? "y" : ""); - } - - function indexOf (array, item, from) { - if (Array.prototype.indexOf) // Use the native array method if available - return array.indexOf(item, from); - for (var i = from || 0; i < array.length; i++) { - if (array[i] === item) - return i; - } - return -1; - } - -}); diff --git a/lib/ace/lib/useragent.js b/lib/ace/lib/useragent.js deleted file mode 100644 index e32d4a5dbe0..00000000000 --- a/lib/ace/lib/useragent.js +++ /dev/null @@ -1,105 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -/* - * I hate doing this, but we need some way to determine if the user is on a Mac - * The reason is that users have different expectations of their key combinations. - * - * Take copy as an example, Mac people expect to use CMD or APPLE + C - * Windows folks expect to use CTRL + C - */ -exports.OS = { - LINUX: "LINUX", - MAC: "MAC", - WINDOWS: "WINDOWS" -}; - -/* - * Return an exports.OS constant - */ -exports.getOS = function() { - if (exports.isMac) { - return exports.OS.MAC; - } else if (exports.isLinux) { - return exports.OS.LINUX; - } else { - return exports.OS.WINDOWS; - } -}; - -// this can be called in non browser environments (e.g. from ace/requirejs/text) -if (typeof navigator != "object") - return; - -var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase(); -var ua = navigator.userAgent; - -// Is the user using a browser that identifies itself as Windows -exports.isWin = (os == "win"); - -// Is the user using a browser that identifies itself as Mac OS -exports.isMac = (os == "mac"); - -// Is the user using a browser that identifies itself as Linux -exports.isLinux = (os == "linux"); - -// 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. -exports.isIE = - (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0) - ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]) - : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie - -exports.isOldIE = exports.isIE && exports.isIE < 9; - -// Is this Firefox or related? -exports.isGecko = exports.isMozilla = ua.match(/ Gecko\/\d+/); - -// Is this Opera -exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]"; - -// Is the user using a browser that identifies itself as WebKit -exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined; - -exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined; - -exports.isAIR = ua.indexOf("AdobeAIR") >= 0; - -exports.isIPad = ua.indexOf("iPad") >= 0; - -exports.isChromeOS = ua.indexOf(" CrOS ") >= 0; - -exports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream; - -if (exports.isIOS) exports.isMac = true; - -}); diff --git a/lib/ace/line_widgets.js b/lib/ace/line_widgets.js deleted file mode 100644 index a7ba708a19f..00000000000 --- a/lib/ace/line_widgets.js +++ /dev/null @@ -1,386 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("./lib/oop"); -var dom = require("./lib/dom"); -var Range = require("./range").Range; - - -function LineWidgets(session) { - this.session = session; - this.session.widgetManager = this; - this.session.getRowLength = this.getRowLength; - this.session.$getWidgetScreenLength = this.$getWidgetScreenLength; - this.updateOnChange = this.updateOnChange.bind(this); - this.renderWidgets = this.renderWidgets.bind(this); - this.measureWidgets = this.measureWidgets.bind(this); - this.session._changedWidgets = []; - this.$onChangeEditor = this.$onChangeEditor.bind(this); - - this.session.on("change", this.updateOnChange); - this.session.on("changeFold", this.updateOnFold); - this.session.on("changeEditor", this.$onChangeEditor); -} - -(function() { - this.getRowLength = function(row) { - var h; - if (this.lineWidgets) - h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; - else - h = 0; - if (!this.$useWrapMode || !this.$wrapData[row]) { - return 1 + h; - } else { - return this.$wrapData[row].length + 1 + h; - } - }; - - this.$getWidgetScreenLength = function() { - var screenRows = 0; - this.lineWidgets.forEach(function(w){ - if (w && w.rowCount && !w.hidden) - screenRows += w.rowCount; - }); - return screenRows; - }; - - this.$onChangeEditor = function(e) { - this.attach(e.editor); - }; - - this.attach = function(editor) { - if (editor && editor.widgetManager && editor.widgetManager != this) - editor.widgetManager.detach(); - - if (this.editor == editor) - return; - - this.detach(); - this.editor = editor; - - if (editor) { - editor.widgetManager = this; - editor.renderer.on("beforeRender", this.measureWidgets); - editor.renderer.on("afterRender", this.renderWidgets); - } - }; - this.detach = function(e) { - var editor = this.editor; - if (!editor) - return; - - this.editor = null; - editor.widgetManager = null; - - editor.renderer.off("beforeRender", this.measureWidgets); - editor.renderer.off("afterRender", this.renderWidgets); - var lineWidgets = this.session.lineWidgets; - lineWidgets && lineWidgets.forEach(function(w) { - if (w && w.el && w.el.parentNode) { - w._inDocument = false; - w.el.parentNode.removeChild(w.el); - } - }); - }; - - this.updateOnFold = function(e, session) { - var lineWidgets = session.lineWidgets; - if (!lineWidgets || !e.action) - return; - var fold = e.data; - var start = fold.start.row; - var end = fold.end.row; - var hide = e.action == "add"; - for (var i = start + 1; i < end; i++) { - if (lineWidgets[i]) - lineWidgets[i].hidden = hide; - } - if (lineWidgets[end]) { - if (hide) { - if (!lineWidgets[start]) - lineWidgets[start] = lineWidgets[end]; - else - lineWidgets[end].hidden = hide; - } else { - if (lineWidgets[start] == lineWidgets[end]) - lineWidgets[start] = undefined; - lineWidgets[end].hidden = hide; - } - } - }; - - this.updateOnChange = function(delta) { - var lineWidgets = this.session.lineWidgets; - if (!lineWidgets) return; - - var startRow = delta.start.row; - var len = delta.end.row - startRow; - - if (len === 0) { - // return - } else if (delta.action == 'remove') { - var removed = lineWidgets.splice(startRow + 1, len); - removed.forEach(function(w) { - w && this.removeLineWidget(w); - }, this); - this.$updateRows(); - } else { - var args = new Array(len); - args.unshift(startRow, 0); - lineWidgets.splice.apply(lineWidgets, args); - this.$updateRows(); - } - }; - - this.$updateRows = function() { - var lineWidgets = this.session.lineWidgets; - if (!lineWidgets) return; - var noWidgets = true; - lineWidgets.forEach(function(w, i) { - if (w) { - noWidgets = false; - w.row = i; - while (w.$oldWidget) { - w.$oldWidget.row = i; - w = w.$oldWidget; - } - } - }); - if (noWidgets) - this.session.lineWidgets = null; - }; - - this.addLineWidget = function(w) { - if (!this.session.lineWidgets) - this.session.lineWidgets = new Array(this.session.getLength()); - - var old = this.session.lineWidgets[w.row]; - if (old) { - w.$oldWidget = old; - if (old.el && old.el.parentNode) { - old.el.parentNode.removeChild(old.el); - old._inDocument = false; - } - } - - this.session.lineWidgets[w.row] = w; - - w.session = this.session; - - var renderer = this.editor.renderer; - if (w.html && !w.el) { - w.el = dom.createElement("div"); - w.el.innerHTML = w.html; - } - if (w.el) { - dom.addCssClass(w.el, "ace_lineWidgetContainer"); - w.el.style.position = "absolute"; - w.el.style.zIndex = 5; - renderer.container.appendChild(w.el); - w._inDocument = true; - } - - if (!w.coverGutter) { - w.el.style.zIndex = 3; - } - if (w.pixelHeight == null) { - w.pixelHeight = w.el.offsetHeight; - } - if (w.rowCount == null) { - w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight; - } - - var fold = this.session.getFoldAt(w.row, 0); - w.$fold = fold; - if (fold) { - var lineWidgets = this.session.lineWidgets; - if (w.row == fold.end.row && !lineWidgets[fold.start.row]) - lineWidgets[fold.start.row] = w; - else - w.hidden = true; - } - - this.session._emit("changeFold", {data:{start:{row: w.row}}}); - - this.$updateRows(); - this.renderWidgets(null, renderer); - this.onWidgetChanged(w); - return w; - }; - - this.removeLineWidget = function(w) { - w._inDocument = false; - w.session = null; - if (w.el && w.el.parentNode) - w.el.parentNode.removeChild(w.el); - if (w.editor && w.editor.destroy) try { - w.editor.destroy(); - } catch(e){} - if (this.session.lineWidgets) { - var w1 = this.session.lineWidgets[w.row]; - if (w1 == w) { - this.session.lineWidgets[w.row] = w.$oldWidget; - if (w.$oldWidget) - this.onWidgetChanged(w.$oldWidget); - } else { - while (w1) { - if (w1.$oldWidget == w) { - w1.$oldWidget = w.$oldWidget; - break; - } - w1 = w1.$oldWidget; - } - } - } - this.session._emit("changeFold", {data:{start:{row: w.row}}}); - this.$updateRows(); - }; - - this.getWidgetsAtRow = function(row) { - var lineWidgets = this.session.lineWidgets; - var w = lineWidgets && lineWidgets[row]; - var list = []; - while (w) { - list.push(w); - w = w.$oldWidget; - } - return list; - }; - - this.onWidgetChanged = function(w) { - this.session._changedWidgets.push(w); - this.editor && this.editor.renderer.updateFull(); - }; - - this.measureWidgets = function(e, renderer) { - var changedWidgets = this.session._changedWidgets; - var config = renderer.layerConfig; - - if (!changedWidgets || !changedWidgets.length) return; - var min = Infinity; - for (var i = 0; i < changedWidgets.length; i++) { - var w = changedWidgets[i]; - if (!w || !w.el) continue; - if (w.session != this.session) continue; - if (!w._inDocument) { - if (this.session.lineWidgets[w.row] != w) - continue; - w._inDocument = true; - renderer.container.appendChild(w.el); - } - - w.h = w.el.offsetHeight; - - if (!w.fixedWidth) { - w.w = w.el.offsetWidth; - w.screenWidth = Math.ceil(w.w / config.characterWidth); - } - - var rowCount = w.h / config.lineHeight; - if (w.coverLine) { - rowCount -= this.session.getRowLineCount(w.row); - if (rowCount < 0) - rowCount = 0; - } - if (w.rowCount != rowCount) { - w.rowCount = rowCount; - if (w.row < min) - min = w.row; - } - } - if (min != Infinity) { - this.session._emit("changeFold", {data:{start:{row: min}}}); - this.session.lineWidgetWidth = null; - } - this.session._changedWidgets = []; - }; - - this.renderWidgets = function(e, renderer) { - var config = renderer.layerConfig; - var lineWidgets = this.session.lineWidgets; - if (!lineWidgets) - return; - var first = Math.min(this.firstRow, config.firstRow); - var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length); - - while (first > 0 && !lineWidgets[first]) - first--; - - this.firstRow = config.firstRow; - this.lastRow = config.lastRow; - - renderer.$cursorLayer.config = config; - for (var i = first; i <= last; i++) { - var w = lineWidgets[i]; - if (!w || !w.el) continue; - if (w.hidden) { - w.el.style.top = -100 - (w.pixelHeight || 0) + "px"; - continue; - } - if (!w._inDocument) { - w._inDocument = true; - renderer.container.appendChild(w.el); - } - var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top; - if (!w.coverLine) - top += config.lineHeight * this.session.getRowLineCount(w.row); - w.el.style.top = top - config.offset + "px"; - - var left = w.coverGutter ? 0 : renderer.gutterWidth; - if (!w.fixedWidth) - left -= renderer.scrollLeft; - w.el.style.left = left + "px"; - - if (w.fullWidth && w.screenWidth) { - w.el.style.minWidth = config.width + 2 * config.padding + "px"; - } - - if (w.fixedWidth) { - w.el.style.right = renderer.scrollBar.getWidth() + "px"; - } else { - w.el.style.right = ""; - } - } - }; - -}).call(LineWidgets.prototype); - - -exports.LineWidgets = LineWidgets; - -}); - - - - diff --git a/lib/ace/loader_build.js b/lib/ace/loader_build.js new file mode 100644 index 00000000000..77505a27cdd --- /dev/null +++ b/lib/ace/loader_build.js @@ -0,0 +1,91 @@ +define(function(require, exports, module) { +"use strict"; + +// configure module loading in ace-builds to remain backwards compatible + +require("./lib/fixoldbrowsers"); +var config = require("./config"); +config.setLoader(function(moduleName, cb) { + require([moduleName], function(module) { + cb(null, module); + }); +}); + +var global = (function() { + return this || typeof window != "undefined" && window; +})(); + +module.exports = function(ace) { + config.init = init; + config.$require = require; + + /** + * Provides access to require in packed noconflict mode + * @param {String} moduleName + * @returns {Object} + **/ + ace.require = require; + + if (typeof define === "function") + ace.define = define; +}; + +// initialization +function init(packaged) { + if (!global || !global.document) + return; + + config.set("packaged", packaged || require.packaged || module.packaged || (global.define && define.packaged)); + + var scriptOptions = {}; + var scriptUrl = ""; + + // Use currentScript.ownerDocument in case this file was loaded from imported document. (HTML Imports) + var currentScript = (document.currentScript || document._currentScript ); // native or polyfill + var currentDocument = currentScript && currentScript.ownerDocument || document; + + if (currentScript && currentScript.src) { + scriptUrl = currentScript.src.split(/[?#]/)[0].split("/").slice(0, -1).join("/") || ""; + } + + var scripts = currentDocument.getElementsByTagName("script"); + for (var i=0; i.json` files keep information about correct tokens and tokenizer states for all modes supported by ace. -They are generated from `text_.txt` or `demo/kitchen-sink/doc/*` with - -```sh -node highlight_rules_test.js -gen -``` - -command. - diff --git a/lib/ace/mode/_test/highlight_rules_test.js b/lib/ace/mode/_test/highlight_rules_test.js deleted file mode 100644 index 8446304ebe1..00000000000 --- a/lib/ace/mode/_test/highlight_rules_test.js +++ /dev/null @@ -1,252 +0,0 @@ -var fs = require("fs"); -var path = require("path"); -if (!fs.existsSync) - fs.existsSync = path.existsSync; - -require("amd-loader"); - -var cwd = __dirname + "/"; -var root = path.normalize(cwd + Array(5).join("../")); - -function jsFileList(path, filter) { - if (!filter) filter = /_test/; - return fs.readdirSync(path).map(function(x) { - if (x.slice(-3) == ".js" && !filter.test(x) && !/\s/.test(x)) - return x.slice(0, -3); - }).filter(Boolean); -} - -function modeList() { - return jsFileList(cwd + "../", /_highlight_rules|_test|_worker|xml_util|_outdent|behaviour|completions/); -} - -function checkModes() { - modeList().forEach(function(modeName, i) { - console.log(padNumber(i+1, 3) + ") check: \u001b[33m" + modeName + "\u001b[0m"); - try { - var Mode = require("../" + modeName).Mode; - } catch(e) { - console.warn("Can't load mode :" + modeName, e); - return; - } - var m = new Mode(); - if (!("lineCommentStart" in m) && !("blockComment" in m)) - console.warn("missing comment in " + modeName); - if (!m.$id) - console.warn("missing id in " + modeName); - if (!m.$behaviour) - console.warn("missing behavior in " + modeName); - var tokenizer = (new Mode).getTokenizer(); - - testComments(m.lineCommentStart, testLineComment, tokenizer, modeName); - testComments(m.blockComment, testBlockComment, tokenizer, modeName); - }); - - function testComments(desc, fn, tokenizer, modeName) { - if (desc) { - if (Array.isArray(desc)) { - desc.forEach(function(x) { - fn(tokenizer, x, modeName); - }); - } else { - fn(tokenizer, desc, modeName); - } - } - } - - function testBlockComment(tokenizer, blockComment, modeName) { - if (blockComment.lineStartOnly) - return; // TODO test - var str = blockComment.start + " " + blockComment.end; - str = blockComment.start + str; - if (blockComment.nestable) - str += blockComment.end; - var data = tokenizer.getLineTokens(str, "start"); - var isBroken = data.tokens.some(function(t) { return !/comment/.test(t.type); }); - if (isBroken) - console.warn("broken blockComment in " + modeName, data); - if (!/start/.test(data.state)) - console.warn("broken state after blockComment in " + modeName, data); - } - - function testLineComment(tokenizer, commentStart, modeName) { - var tokens = tokenizer.getLineTokens(commentStart + " ", "start").tokens; - if (!/comment/.test(tokens[0].type)) - console.warn("broken lineCommentStart in " + modeName); - } -} - -function generateTestData(names, force) { - var docRoot = root + "/demo/kitchen-sink/docs"; - var docs = fs.readdirSync(docRoot); - var specialDocs = fs.readdirSync(cwd); - var modes = modeList(); - - // console.log("Docs:", docs); - // console.log("Modes:", modes); - - docs.forEach(function(docName) { - var p = docName.toLowerCase().split("."); - if (!p[1]) - return; - var modeName; - if (modes.indexOf(p[0]) != -1) - modeName = p[0]; - else if (modes.indexOf(p[1]) != -1) - modeName = p[1]; - else - modeName = {"txt": "text", cpp: "c_cpp"}[p[1]]; - - if (names && names.length && names.indexOf(modeName) == -1) - return; - - var outputPath = cwd + "tokens_" + modeName + ".json"; - try { - var oldOutput = require(outputPath); - } catch(e) {} - if (oldOutput && !force) { - var oldText = oldOutput.map(function(x) { - if (x.length > 1 && typeof x[x.length - 1] == "string") - return x[x.length - 1]; - return x.slice(1).map(function(tok) { - return tok[1]; - }).join(""); - }).join("\n"); - } - - var filePath = "text_" + modeName + ".txt"; - if (specialDocs.indexOf(filePath) !== -1) { - filePath = cwd + filePath; - } else { - filePath = docRoot + "/" + docName; - // oldText = ""; - } - var text = oldText ||fs.readFileSync(filePath, "utf8"); - - try { - var Mode = require("../" + modeName).Mode; - } catch(e) { - console.warn("Can't load mode :" + modeName, p, e); - return; - } - console.log(modeName); - var tokenizer = new Mode().getTokenizer(); - - var state = "start"; - var data = text.split(/\r\n|\r|\n/).map(function(line) { - var data = tokenizer.getLineTokens(line, state); - var tmp = []; - tmp.push(JSON.stringify(data.state)); - var tokenizedLine = ""; - data.tokens.forEach(function(x) { - tokenizedLine += x.value; - tmp.push(JSON.stringify([x.type, x.value])); - }); - if (tokenizedLine != line) - tmp.push(JSON.stringify(line)); - state = data.state; - return tmp.join(",\n "); - }); - - var jsonStr = "[[\n " + data.join("\n],[\n ") + "\n]]"; - - if (oldOutput && JSON.stringify(JSON.parse(jsonStr)) == JSON.stringify(oldOutput)) - return; - - fs.writeFileSync(outputPath, jsonStr, "utf8"); - }); -} - -function test(startAt) { - var modes = fs.readdirSync(cwd).map(function(x) { - return (x.match(/tokens_(.*).json/) || {})[1]; - }).filter(function(x){return !!x;}); - - for (var i = Math.max(0, startAt||0); i < modes.length; i++) - testMode(modes[i], i); - - console.log("\u001b[32m" + "all ok" + "\u001b[0m"); -} -function testMode(modeName, i) { - console.log(padNumber(i+1, 3) + ") testing: \u001b[33m" + modeName + "\u001b[0m"); - - var text = fs.readFileSync(cwd + "tokens_" + modeName + ".json", "utf8"); - var data = JSON.parse(text); - var Mode = require("../" + modeName).Mode; - var tokenizer = new Mode().getTokenizer(); - - var state = "start"; - data.forEach(function(lineData) { - lineData.values = []; - lineData.types = []; - lineData.state = lineData.shift(); - var line = null; - if (typeof lineData[lineData.length - 1] == "string") - line = lineData.pop(); - lineData.forEach(function(x) { - lineData.types.push(x[0]); - lineData.values.push(x[1]); - }); - if (typeof line != "string") - line = lineData.values.join(""); - - var tokens = tokenizer.getLineTokens(line, state); - var values = tokens.tokens.map(function(x) {return x.value;}); - var types = tokens.tokens.map(function(x) {return x.type;}); - - var err = testEqual([ - JSON.stringify(lineData.state), JSON.stringify(tokens.state), - lineData.types, types, - lineData.values, values]); - - if (err) { - console.log(line); - throw "error"; - } - - state = tokens.state; - }); -} -function testEqual(a) { - var err; - if (a[0] + "" !== a[1] + "") { - console.log(a[0],a[1]); - err = 1; - } - - if ( a[2] + "" !== a[3] + "" || a[4] + "" !== a[5] + "") { - arrayDiff(a[2],a[3]); - arrayDiff(a[4],a[5]); - err = 1; - } - return err; -} -function arrayDiff(a1, a2) { - var l = Math.max(a1.length, a2.length); - var out = []; - for (var i = 0; i < l; i++) { - out.push("\n", padNumber(i+1, 3), ") "); - if (a1[i] !== a2[i]) - out.push("\u001b[31m", a1[i], "\u001b[0m != \u001b[32m", a2[i], "\u001b[0m"); - else - out.push(a1[i]); - } - console.log(out.join("")); -} -function padNumber(num, digits) { - return (" " + num).slice(-digits); -} - -// cli -var arg = process.argv[2]; -if (!arg) { - test(); - checkModes(); -} else if (/--?g(en)?/.test(arg)) - generateTestData(process.argv.splice(3)); -else if (/--?c(heck)?/.test(arg)) - checkModes(); -else if (/\d+/.test(arg)) - test(parseInt(process.argv[2],10) || 0); -else - testMode(arg, -1); \ No newline at end of file diff --git a/lib/ace/mode/_test/text_gobstones.txt b/lib/ace/mode/_test/text_gobstones.txt deleted file mode 100644 index 4768d5f9423..00000000000 --- a/lib/ace/mode/_test/text_gobstones.txt +++ /dev/null @@ -1,19 +0,0 @@ -program { - /* - * A gobstons multiline comment - * Taken from: - * http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/" - */ - sumar(2, 3) - } - function sumar(a, b) { - r := a + b - } - // unreachable code - -- unreachable code - # unreachable code - procedure hacerAlgo() { - Mover(Este) - Poner(Rojo) - Sacar(Azul) - } \ No newline at end of file diff --git a/lib/ace/mode/_test/text_javascript.txt b/lib/ace/mode/_test/text_javascript.txt deleted file mode 100644 index 390709ca10e..00000000000 --- a/lib/ace/mode/_test/text_javascript.txt +++ /dev/null @@ -1,100 +0,0 @@ -//test: tokenize 'standard' functions -string.charCodeAt(23); document.getElementById('test'); console.log('Here it is');"; -test: /**tokenize doc*/ comment -/**tokenize doc comment with @tag {}*/ -//test: tokenize parens - var $line$ = "[{( )}]"; -//test tokenize arithmetic expression which looks like a regexp -a/b/c -a/=b/c -//test tokenize reg exps -a=/b/g -a+/b/g -a = 1 + /2 + 1/gimyxk -a=/a/ / /a/ -case /a/.test(c) -//test tokenize multi-line comment containing a single line comment -noRegex -/* foo // bar */ -canBeRegex; -/* foo // bar */ -// test tokenize identifier with umlauts -fu?e -// test // is not a regexp -{ // 123 -//test skipping escaped chars -'Meh\\nNeh' -console.log('\\u1232Feh' -"test multiline\ - strings" -a=' -b="\ -still a string - - -function foo(items, nada) { - for (var i=0; i>=t<>r>>>s>=0b1 - -foo.protoype.d = function(a, b, - c, d) -foo.d =function(a, b) -foo.d =function(a, /*****/ d"string" - -
      {2} - }> -1 { ++x } -
      - -var o = { - t:`${[].map(x => { - return x - })}` -}; diff --git a/lib/ace/mode/_test/text_lucene.txt b/lib/ace/mode/_test/text_lucene.txt deleted file mode 100644 index c71f2680d1a..00000000000 --- a/lib/ace/mode/_test/text_lucene.txt +++ /dev/null @@ -1,16 +0,0 @@ -test: recognises AND as keyword -test: recognises OR as keyword -test: recognises NOT as keyword -test: recognises "hello this is dog" as string -test: recognises -"hello this is dog" as negation with string -test: recognises ~100 as text with proximity -test: recognises "hello this is dog"~100 as string with proximity -test: recognises raw:"hello this is dog" as keyword -test: recognises raw:foo as"keyword' -test: recognises "(" as opening parenthesis -test: recognises ")" as closing parenthesis -test: recognises foo* as text with asterisk -test: recognises foo? as text with interro -test: recognises single word as text - foo - \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_gobstones.json b/lib/ace/mode/_test/tokens_gobstones.json deleted file mode 100644 index 4ecb2c4bdc7..00000000000 --- a/lib/ace/mode/_test/tokens_gobstones.json +++ /dev/null @@ -1,113 +0,0 @@ -[[ - "start", - ["keyword","program"], - ["text"," "], - ["lparen","{"] -],[ - "comment", - ["text"," "], - ["comment","/*"] -],[ - "comment", - ["comment"," * A gobstons multiline comment"] -],[ - "comment", - ["comment"," * Taken from:"] -],[ - "comment", - ["comment"," * http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/\""] -],[ - "start", - ["comment"," */"] -],[ - "start", - ["text"," "], - ["identifier","sumar"], - ["lparen","("], - ["constant.numeric","2"], - ["keyword.operator",","], - ["text"," "], - ["constant.numeric","3"], - ["rparen",")"] -],[ - "start", - ["text"," "], - ["rparen","}"] -],[ - "start", - ["text"," "], - ["keyword","function"], - ["text"," "], - ["identifier","sumar"], - ["lparen","("], - ["identifier","a"], - ["keyword.operator",","], - ["text"," "], - ["identifier","b"], - ["rparen",")"], - ["text"," "], - ["lparen","{"] -],[ - "start", - ["text"," "], - ["identifier","r"], - ["text"," "], - ["keyword.operator",":="], - ["text"," "], - ["identifier","a"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["identifier","b"] -],[ - "start", - ["text"," "], - ["rparen","}"] -],[ - "start", - ["text"," "], - ["comment","// unreachable code"] -],[ - "start", - ["text"," "], - ["comment","-- unreachable code"] -],[ - "start", - ["text"," "], - ["comment","# unreachable code"] -],[ - "start", - ["text"," "], - ["keyword","procedure"], - ["text"," "], - ["identifier","hacerAlgo"], - ["lparen","("], - ["rparen",")"], - ["text"," "], - ["lparen","{"] -],[ - "start", - ["text"," "], - ["support.function","Mover"], - ["lparen","("], - ["support.type","Este"], - ["rparen",")"] -],[ - "start", - ["text"," "], - ["support.function","Poner"], - ["lparen","("], - ["support.type","Rojo"], - ["rparen",")"] -],[ - "start", - ["text"," "], - ["support.function","Sacar"], - ["lparen","("], - ["support.type","Azul"], - ["rparen",")"] -],[ - "start", - ["text"," "], - ["rparen","}"] -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_java.json b/lib/ace/mode/_test/tokens_java.json deleted file mode 100644 index c55649a34b2..00000000000 --- a/lib/ace/mode/_test/tokens_java.json +++ /dev/null @@ -1,128 +0,0 @@ -[[ - "start", - ["keyword","public"], - ["text"," "], - ["keyword","class"], - ["text"," "], - ["identifier","InfiniteLoop"], - ["text"," "], - ["lparen","{"] -],[ - "start" -],[ - "comment", - ["text"," "], - ["comment","/*"] -],[ - "comment", - ["comment"," * This will cause the program to hang..."] -],[ - "comment", - ["comment"," *"] -],[ - "comment", - ["comment"," * Taken from:"] -],[ - "comment", - ["comment"," * http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/"] -],[ - "start", - ["comment"," */"] -],[ - "start", - ["text"," "], - ["keyword","public"], - ["text"," "], - ["keyword","static"], - ["text"," "], - ["keyword","void"], - ["text"," "], - ["identifier","main"], - ["lparen","("], - ["support.function","String"], - ["lparen","["], - ["rparen","]"], - ["text"," "], - ["identifier","args"], - ["rparen",")"], - ["text"," "], - ["lparen","{"] -],[ - "start", - ["text"," "], - ["keyword","double"], - ["text"," "], - ["identifier","d"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["support.function","Double"], - ["text","."], - ["identifier","parseDouble"], - ["lparen","("], - ["string","\"2.2250738585072012e-308\""], - ["rparen",")"], - ["text",";"] -],[ - "start" -],[ - "start", - ["text"," "], - ["comment","// unreachable code"] -],[ - "start", - ["text"," "], - ["support.function","System"], - ["text","."], - ["identifier","out"], - ["text","."], - ["identifier","println"], - ["lparen","("], - ["string","\"Value: \""], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["identifier","d"], - ["rparen",")"], - ["text",";"] -],[ - "start", - ["text"," "], - ["keyword","int"], - ["text"," "], - ["identifier","exports"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["constant.numeric","10"], - ["text",";"] -],[ - "start", - ["text"," "], - ["keyword","int"], - ["text"," "], - ["identifier","requires"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["constant.numeric","20"], - ["text",";"] -],[ - "start", - ["text"," "], - ["keyword","int"], - ["text"," "], - ["identifier","open"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["constant.numeric","30"], - ["text",";"] -],[ - "start", - ["text"," "], - ["rparen","}"] -],[ - "start", - ["rparen","}"] -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_javascript.json b/lib/ace/mode/_test/tokens_javascript.json deleted file mode 100644 index 8759595b6d6..00000000000 --- a/lib/ace/mode/_test/tokens_javascript.json +++ /dev/null @@ -1,736 +0,0 @@ -[[ - "start", - ["comment","//test: tokenize 'standard' functions"] -],[ - "no_regex", - ["identifier","string"], - ["punctuation.operator","."], - ["support.function","charCodeAt"], - ["paren.lparen","("], - ["constant.numeric","23"], - ["paren.rparen",")"], - ["punctuation.operator",";"], - ["text"," "], - ["variable.language","document"], - ["punctuation.operator","."], - ["support.function.dom","getElementById"], - ["paren.lparen","("], - ["string","'test'"], - ["paren.rparen",")"], - ["punctuation.operator",";"], - ["text"," "], - ["storage.type","console"], - ["punctuation.operator","."], - ["support.function.firebug","log"], - ["paren.lparen","("], - ["string","'Here it is'"], - ["paren.rparen",")"], - ["punctuation.operator",";"], - ["string","\";"] -],[ - "no_regex", - ["identifier","test"], - ["punctuation.operator",":"], - ["text"," "], - ["comment.doc","/**tokenize doc*/"], - ["text"," "], - ["identifier","comment"] -],[ - "no_regex", - ["comment.doc","/**tokenize doc comment with "], - ["comment.doc.tag","@tag"], - ["comment.doc"," {}*/"] -],[ - "no_regex", - ["comment","//test: tokenize parens"] -],[ - "start", - ["text"," "], - ["storage.type","var"], - ["text"," "], - ["identifier","$line$"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["string","\"[{( )}]\""], - ["punctuation.operator",";"] -],[ - "start", - ["comment","//test tokenize arithmetic expression which looks like a regexp"] -],[ - "no_regex", - ["identifier","a"], - ["keyword.operator","/"], - ["identifier","b"], - ["keyword.operator","/"], - ["identifier","c"] -],[ - "no_regex", - ["identifier","a"], - ["keyword.operator","/="], - ["identifier","b"], - ["keyword.operator","/"], - ["identifier","c"] -],[ - "no_regex", - ["comment","//test tokenize reg exps"] -],[ - "no_regex", - ["identifier","a"], - ["keyword.operator","="], - ["string.regexp","/b/g"] -],[ - "no_regex", - ["identifier","a"], - ["keyword.operator","+"], - ["string.regexp","/b/g"] -],[ - "no_regex", - ["identifier","a"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["constant.numeric","1"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["string.regexp","/2 "], - ["constant.language.escape","+"], - ["string.regexp"," 1/gimyx"], - ["identifier","k"] -],[ - "no_regex", - ["identifier","a"], - ["keyword.operator","="], - ["string.regexp","/a/"], - ["text"," "], - ["keyword.operator","/"], - ["text"," "], - ["string.regexp","/a/"] -],[ - "no_regex", - ["keyword","case"], - ["text"," "], - ["string.regexp","/a/"], - ["punctuation.operator","."], - ["support.function","test"], - ["paren.lparen","("], - ["identifier","c"], - ["paren.rparen",")"] -],[ - "no_regex", - ["comment","//test tokenize multi-line comment containing a single line comment"] -],[ - "no_regex", - ["identifier","noRegex"] -],[ - "no_regex", - ["comment","/* foo // bar */"] -],[ - "start", - ["identifier","canBeRegex"], - ["punctuation.operator",";"] -],[ - "start", - ["comment","/* foo // bar */"] -],[ - "start", - ["comment","// test tokenize identifier with umlauts"] -],[ - "no_regex", - ["identifier","fu"], - ["punctuation.operator","?"], - ["identifier","e"] -],[ - "no_regex", - ["comment","// test // is not a regexp"] -],[ - "start", - ["paren.lparen","{"], - ["text"," "], - ["comment","// 123"] -],[ - "start", - ["comment","//test skipping escaped chars"] -],[ - "no_regex", - ["string","'Meh"], - ["constant.language.escape","\\\\"], - ["string","nNeh'"] -],[ - "no_regex", - ["storage.type","console"], - ["punctuation.operator","."], - ["support.function.firebug","log"], - ["paren.lparen","("], - ["string","'"], - ["constant.language.escape","\\\\"], - ["string","u1232Feh'"] -],[ - "qqstring", - ["string","\"test multiline\\"] -],[ - "no_regex", - ["string"," strings\""] -],[ - "no_regex", - ["identifier","a"], - ["keyword.operator","="], - ["text","'"] -],[ - "qqstring", - ["identifier","b"], - ["keyword.operator","="], - ["string","\"\\"] -],[ - "no_regex", - ["string","still a string"] -],[ - "no_regex", - ["text"," "] -],[ - "no_regex", - ["text"," "] -],[ - "start", - ["storage.type","function"], - ["text"," "], - ["entity.name.function","foo"], - ["paren.lparen","("], - ["variable.parameter","items"], - ["punctuation.operator",", "], - ["variable.parameter","nada"], - ["paren.rparen",")"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," "], - ["keyword","for"], - ["text"," "], - ["paren.lparen","("], - ["storage.type","var"], - ["text"," "], - ["identifier","i"], - ["keyword.operator","="], - ["constant.numeric","0"], - ["punctuation.operator",";"], - ["text"," "], - ["identifier","i"], - ["keyword.operator","<"], - ["identifier","items"], - ["punctuation.operator","."], - ["support.constant","length"], - ["punctuation.operator",";"], - ["text"," "], - ["identifier","i"], - ["keyword.operator","++"], - ["paren.rparen",")"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," "], - ["support.function","alert"], - ["paren.lparen","("], - ["identifier","items"], - ["paren.lparen","["], - ["identifier","i"], - ["paren.rparen","]"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["string","\"juhu"], - ["constant.language.escape","\\n"], - ["string","\""], - ["paren.rparen",")"], - ["punctuation.operator",";"] -],[ - "no_regex", - ["text"," "], - ["paren.rparen","}"], - ["text","\t"], - ["comment","// Real Tab."] -],[ - "no_regex", - ["paren.rparen","}"] -],[ - "no_regex" -],[ - "no_regex", - ["identifier","regexp"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["string.regexp","/p"], - ["constant.language.delimiter","|"], - ["string.regexp","p/"], - ["text"," "], - ["comment","// ends here"] -],[ - "no_regex" -],[ - "no_regex", - ["identifier","r"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["string.regexp","/d"], - ["constant.language.escape","{1,2}?"], - ["string.regexp","f{e}"], - ["invalid","++"], - ["string.regexp","r"], - ["constant.language.escape","*?"], - ["regexp.keyword.operator","\\d"], - ["constant.language.escape","+?[]"], - ["string.regexp","r"], - ["constant.language.escape","[^"], - ["string.regexp.charachterclass","r"], - ["constant.language.escape","-"], - ["string.regexp.charachterclass","o"], - ["regexp.charclass.keyword.operator","\\f\\f"], - ["string.regexp.charachterclass","["], - ["regexp.charclass.keyword.operator","\\f"], - ["constant.language.escape","]?"], - ["string.regexp","r"], - ["invalid","{7}+"], - ["string.regexp","r"], - ["regexp.keyword.operator","\\{"], - ["string.regexp","7}"], - ["constant.language.escape","+"], - ["string.regexp","rr--rr"], - ["constant.language.escape","$^(?:"], - ["string.regexp","d"], - ["constant.language.delimiter","|"], - ["string.regexp","s"], - ["constant.language.escape",")(?="], - ["string.regexp","a"], - ["constant.language.delimiter","|"], - ["constant.language.escape",")(?!"], - ["string.regexp","y"], - ["constant.language.escape",")[]"], - ["constant.language.delimiter","|"], - ["invalid","$?"], - ["constant.language.delimiter","|"], - ["invalid","^*"], - ["string.regexp","/"], - ["text"," "], - ["identifier","o"] -],[ - "no_regex", - ["identifier","a"], - ["keyword.operator","="], - ["string.regexp","/a/"], - ["text"," "], - ["identifier","jk"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["string.regexp","/ /"], - ["text"," "], - ["keyword.operator","/"], - ["text"," "], - ["string.regexp","/ /"] -],[ - "no_regex", - ["text"," "], - ["comment.doc","/************************************/"] -],[ - "no_regex", - ["comment.doc","/** total mess, tricky to highlight**/"] -],[ - "no_regex" -],[ - "start", - ["storage.type","function"], - ["text"," "], - ["paren.lparen","("], - ["paren.rparen",")"], - ["text"," "], - ["paren.lparen","{"] -],[ - "doc-start", - ["text","\t"], - ["comment.doc","/**"] -],[ - "doc-start", - ["comment.doc","\t * docComment"] -],[ - "no_regex", - ["comment.doc","\t **/"] -],[ - "no_regex", - ["text","\t"], - ["identifier","r"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["string.regexp","/u"], - ["regexp.keyword.operator","\\t"], - ["constant.language.escape","*"], - ["string.regexp","/"] -],[ - "no_regex", - ["text","\t"], - ["identifier","g"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["constant.numeric","1.00"], - ["identifier","E"], - ["keyword.operator","^"], - ["constant.numeric","1"], - ["punctuation.operator",","], - ["text"," "], - ["identifier","y"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["constant.numeric","1.2"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric","1."], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric",".2"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric","052"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric","0O7"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric","0x25"] -],[ - "no_regex", - ["text","\t"], - ["identifier","t"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["paren.lparen","["], - ["string","'d'"], - ["punctuation.operator",","], - ["text"," "], - ["string","''"], - ["paren.rparen","]"] -],[ - "no_regex", - ["paren.rparen","}"] -],[ - "start", - ["storage.type","function"], - ["text"," "], - ["paren.lparen","("], - ["paren.rparen",")"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text","\t"], - ["comment","/* eee */"] -],[ - "no_regex", - ["paren.rparen","}"] -],[ - "no_regex" -],[ - "qqstring", - ["string","\"s\\"] -],[ - "no_regex", - ["string","s"], - ["constant.language.escape","\\u7824"], - ["string","sss"], - ["constant.language.escape","\\u"], - ["string","1\""] -],[ - "no_regex" -],[ - "qstring", - ["string","'\\"] -],[ - "no_regex", - ["string","string'"] -],[ - "no_regex" -],[ - "no_regex", - ["text","'"] -],[ - "no_regex", - ["identifier","string"], - ["text","'"] -],[ - "no_regex" -],[ - "no_regex", - ["string","\"trailing space"], - ["constant.language.escape","\\ "], - ["string"," "] -],[ - "no_regex", - ["string","\" \""], - ["text"," "], - ["keyword.operator","/"], - ["identifier","not"], - ["text"," "], - ["identifier","a"], - ["text"," "], - ["identifier","regexp"], - ["keyword.operator","/"], - ["identifier","g"] -],[ - "no_regex" -],[ - "doc-start", - ["comment.doc","/**"] -],[ - "doc-start", - ["comment.doc"," *doc"] -],[ - "no_regex", - ["comment.doc"," */"] -],[ - "no_regex" -],[ - "start", - ["identifier","a"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text","\t"], - ["string","'a'"], - ["punctuation.operator",":"], - ["text"," "], - ["identifier","b"], - ["punctuation.operator",","] -],[ - "no_regex", - ["text","\t"], - ["string","'g'"], - ["text",":"], - ["text"," "], - ["storage.type","function"], - ["paren.lparen","("], - ["variable.parameter","t"], - ["paren.rparen",")"] -],[ - "no_regex", - ["text","\t"], - ["entity.name.function","gta"], - ["punctuation.operator",":"], - ["storage.type","function"], - ["paren.lparen","("], - ["variable.parameter","a"], - ["punctuation.operator",","], - ["variable.parameter","b"], - ["paren.rparen",")"] -],[ - "no_regex", - ["paren.rparen","}"] -],[ - "no_regex" -],[ - "no_regex", - ["identifier","z"], - ["keyword.operator",">>="], - ["identifier","t"], - ["keyword.operator","<<"], - ["identifier","f"], - ["keyword.operator",">>"], - ["identifier","r"], - ["keyword.operator",">>>"], - ["identifier","s"], - ["keyword.operator",">="], - ["constant.numeric","0b1"] -],[ - "no_regex" -],[ - "function_arguments", - ["identifier","foo"], - ["punctuation.operator","."], - ["storage.type","protoype"], - ["punctuation.operator","."], - ["entity.name.function","d"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["storage.type","function"], - ["paren.lparen","("], - ["variable.parameter","a"], - ["punctuation.operator",", "], - ["variable.parameter","b"], - ["punctuation.operator",","] -],[ - "no_regex", - ["punctuation.operator"," "], - ["variable.parameter","c"], - ["punctuation.operator",", "], - ["variable.parameter","d"], - ["paren.rparen",")"] -],[ - "no_regex", - ["storage.type","foo"], - ["punctuation.operator","."], - ["entity.name.function","d"], - ["text"," "], - ["keyword.operator","="], - ["storage.type","function"], - ["paren.lparen","("], - ["variable.parameter","a"], - ["punctuation.operator",", "], - ["variable.parameter","b"], - ["paren.rparen",")"] -],[ - "no_regex", - ["storage.type","foo"], - ["punctuation.operator","."], - ["entity.name.function","d"], - ["text"," "], - ["keyword.operator","="], - ["storage.type","function"], - ["paren.lparen","("], - ["variable.parameter","a"], - ["punctuation.operator",", "], - ["comment.doc","/*****/"], - ["text"," "], - ["identifier","d"], - ["string","\"string\""], - ["text"," "] -],[ - "no_regex" -],[ - "no_regex", - ["keyword.operator","<"], - ["identifier","div"] -],[ - ["start","jsxAttributes","jsxAttributes","jsx",1], - ["identifier","z"], - ["keyword.operator","="], - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","div"], - ["text.tag-whitespace.xml"," "], - ["paren.quasi.start","{"], - ["keyword.operator","..."], - ["variable.language","this"], - ["punctuation.operator","."], - ["identifier","props"], - ["paren.quasi.end","}"], - ["text.tag-whitespace.xml"," "], - ["entity.other.attribute-name.xml","x"], - ["keyword.operator.attribute-equals.xml","="], - ["paren.quasi.start","{"], - ["constant.numeric","1"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric","2"], - ["paren.quasi.end","}"], - ["text.tag-whitespace.xml"," "], - ["entity.other.attribute-name.xml","y"], - ["keyword.operator.attribute-equals.xml","="], - ["string.attribute-value.xml","\"z{a}b"], - ["constant.language.escape.reference.xml","&"], - ["string.attribute-value.xml","\""], - ["text.tag-whitespace.xml"," "], - ["entity.other.attribute-name.xml","t"], - ["keyword.operator.attribute-equals.xml","="], - ["paren.quasi.start","{"] -],[ - ["start","jsxAttributes","jsxAttributes","jsx",1], - ["text"," "], - ["constant.numeric","1"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","a"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["paren.quasi.start","{"], - ["constant.numeric","2"], - ["paren.quasi.end","}"], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - ["jsx",1], - ["text"," "], - ["paren.quasi.end","}"], - ["meta.tag.punctuation.tag-close.xml",">"] -],[ - ["jsx",1], - ["string","1 "], - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","a"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["string"," "], - ["paren.quasi.start","{"], - ["text"," "], - ["keyword.operator","++"], - ["identifier","x"], - ["text"," "], - ["paren.quasi.end","}"], - ["string"," "], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start" -],[ - "start", - ["storage.type","var"], - ["text"," "], - ["identifier","o"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["paren.lparen","{"] -],[ - ["start","no_regex","start","string.quasi.start","string.quasi.start","no_regex"], - ["text"," "], - ["identifier","t"], - ["punctuation.operator",":"], - ["string.quasi.start","`"], - ["paren.quasi.start","${"], - ["paren.lparen","["], - ["paren.rparen","]"], - ["punctuation.operator","."], - ["identifier","map"], - ["paren.lparen","("], - ["identifier","x"], - ["text"," "], - ["storage.type","=>"], - ["text"," "], - ["paren.lparen","{"] -],[ - ["#tmp","no_regex","start","no_regex","start","string.quasi.start","string.quasi.start","no_regex"], - ["text"," "], - ["keyword","return"], - ["text"," "], - ["identifier","x"] -],[ - "no_regex", - ["text"," "], - ["paren.rparen","})"], - ["paren.quasi.end","}"], - ["string.quasi.end","`"] -],[ - "start", - ["paren.rparen","}"], - ["punctuation.operator",";"] -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_jsx.json b/lib/ace/mode/_test/tokens_jsx.json deleted file mode 100644 index d1a740b0907..00000000000 --- a/lib/ace/mode/_test/tokens_jsx.json +++ /dev/null @@ -1,51 +0,0 @@ -[[ - "comment", - ["comment","/*EXPECTED"] -],[ - "comment", - ["comment","hello world!"] -],[ - "start", - ["comment","*/"] -],[ - "start", - ["keyword","class"], - ["text"," "], - ["language.support.class","Test"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," "], - ["keyword","static"], - ["text"," "], - ["storage.type","function"], - ["text"," "], - ["entity.name.function","run"], - ["paren.lparen","("], - ["paren.rparen",")"], - ["text"," "], - ["punctuation.operator",":"], - ["text"," "], - ["keyword","void"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," "], - ["comment","// console.log(\"hello world!\");"] -],[ - "start", - ["text"," "], - ["keyword","log"], - ["text"," "], - ["string","\"hello world!\""], - ["punctuation.operator",";"] -],[ - "start", - ["text"," "], - ["paren.rparen","}"] -],[ - "start", - ["paren.rparen","}"] -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_kotlin.json b/lib/ace/mode/_test/tokens_kotlin.json deleted file mode 100644 index af188cf165e..00000000000 --- a/lib/ace/mode/_test/tokens_kotlin.json +++ /dev/null @@ -1,843 +0,0 @@ -[[ - "start", - ["punctuation.definition.comment.kotlin","/*"], - ["comment.block.kotlin","Taken from http://try.kotlinlang.org/#/Examples/Longer%20examples/Life/Life.kt"], - ["punctuation.definition.comment.kotlin","*/"] -],[ - "punctuation.definition.comment.kotlin", - ["punctuation.definition.comment.kotlin","/*"], - ["comment.block.kotlin","*"] -],[ - "punctuation.definition.comment.kotlin", - ["comment.block.kotlin"," * This is a straightforward implementation of The Game of Life"] -],[ - "punctuation.definition.comment.kotlin", - ["comment.block.kotlin"," * See http://en.wikipedia.org/wiki/Conway's_Game_of_Life"] -],[ - "start", - ["comment.block.kotlin"," "], - ["punctuation.definition.comment.kotlin","*/"] -],[ - "start", - ["keyword.other.kotlin","package"], - ["text"," "], - ["entity.name.package.kotlin","life"] -],[ - "start" -],[ - "punctuation.definition.comment.kotlin", - ["punctuation.definition.comment.kotlin","/*"] -],[ - "punctuation.definition.comment.kotlin", - ["comment.block.kotlin"," * A field where cells live. Effectively immutable"] -],[ - "start", - ["comment.block.kotlin"," "], - ["punctuation.definition.comment.kotlin","*/"] -],[ - ["text7","text5"], - ["text","class"], - ["text"," "], - ["entity.name.type.class.kotlin","Field"], - ["text","("] -],[ - ["text7","text5"], - ["text"," "], - ["storage.modifier.kotlin","val"], - ["text"," "], - ["variable.parameter.function.kotlin","width"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",","] -],[ - ["text7","text5"], - ["text"," "], - ["storage.modifier.kotlin","val"], - ["text"," "], - ["variable.parameter.function.kotlin","height"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",","] -],[ - ["text7","text5"], - ["text"," "], - ["keyword.operator.arithmetic.kotlin","//"], - ["text"," "], - ["variable.parameter.function.kotlin","This"], - ["text"," "], - ["variable.parameter.function.kotlin","function"], - ["text"," "], - ["variable.parameter.function.kotlin","tells"], - ["text"," "], - ["variable.parameter.function.kotlin","the"], - ["text"," "], - ["variable.parameter.function.kotlin","constructor"], - ["text"," "], - ["variable.parameter.function.kotlin","which"], - ["text"," "], - ["variable.parameter.function.kotlin","cells"], - ["text"," "], - ["variable.parameter.function.kotlin","are"], - ["text"," "], - ["variable.parameter.function.kotlin","alive"] -],[ - "start", - ["text"," "], - ["keyword.operator.arithmetic.kotlin","//"], - ["text"," "], - ["keyword.control.kotlin","if"], - ["text"," "], - ["variable.parameter.function.kotlin","init"], - ["text","("], - ["variable.parameter.function.kotlin","i"], - ["text",", "], - ["variable.parameter.function.kotlin","j"], - ["text",") is true, the cell ("], - ["variable.parameter.function.kotlin","i"], - ["text",", "], - ["variable.parameter.function.kotlin","j"], - ["text",") is alive"] -],[ - "start", - ["text"," init"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," ("], - ["storage.type.buildin.kotlin","Int"], - ["text",", "], - ["storage.type.buildin.kotlin","Int"], - ["text",") "], - ["keyword.operator.declaration.kotlin","->"], - ["text"," "], - ["storage.type.buildin.kotlin","Boolean"] -],[ - "text", - ["text",") {"] -],[ - "text", - ["text"," "], - ["storage.modifier.kotlin","private"], - ["text"," "], - ["keyword.other.kotlin","val"], - ["text"," "], - ["entity.name.variable.kotlin","live"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," Array> "], - ["keyword.operator.assignment.kotlin","="], - ["text"," Array(height) { i "], - ["keyword.operator.declaration.kotlin","->"], - ["text"," Array(width) { j "], - ["keyword.operator.declaration.kotlin","->"], - ["text"," init(i, j) } }"] -],[ - "text" -],[ - ["text17","text"], - ["text"," "], - ["storage.modifier.kotlin","private"], - ["text"," "], - ["keyword.other.kotlin","fun"], - ["text"," "], - ["entity.name.function.kotlin","liveCount"], - ["text","("], - ["variable.parameter.function.kotlin","i"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",", "], - ["variable.parameter.function.kotlin","j"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",")"] -],[ - ["text3","keyword.operator.assignment.kotlin33","keyword.operator.assignment.kotlin33","text17","text17","text"], - ["text"," "], - ["keyword.operator.assignment.kotlin","="], - ["text"," "], - ["keyword.control.kotlin","if"], - ["text"," (i "], - ["storage.modifier.kotlin","in"], - ["text"," "], - ["constant.numeric.kotlin","0"], - ["keyword.operator.dot.kotlin",".."], - ["text","height "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text"," "], - ["keyword.operator.logical.kotlin","&&"] -],[ - ["text3","keyword.operator.assignment.kotlin33","keyword.operator.assignment.kotlin33","text17","text17","text"], - ["text"," j "], - ["storage.modifier.kotlin","in"], - ["text"," "], - ["constant.numeric.kotlin","0"], - ["keyword.operator.dot.kotlin",".."], - ["text","width "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text"," "], - ["keyword.operator.logical.kotlin","&&"] -],[ - ["text17","text"], - ["text"," live[i][j]) "], - ["constant.numeric.kotlin","1"], - ["text"," "], - ["keyword.control.kotlin","else"], - ["text"," "], - ["constant.numeric.kotlin","0"] -],[ - "text" -],[ - "text", - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," How many neighbors of (i, j) are alive?"] -],[ - ["keyword.operator.assignment.kotlin33","text17","text17","text"], - ["text"," "], - ["keyword.other.kotlin","fun"], - ["text"," "], - ["entity.name.function.kotlin","liveNeighbors"], - ["text","("], - ["variable.parameter.function.kotlin","i"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",", "], - ["variable.parameter.function.kotlin","j"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",") "], - ["keyword.operator.assignment.kotlin","="] -],[ - ["text17","text"], - ["text"," liveCount(i "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",", j "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",") "], - ["keyword.operator.arithmetic.kotlin","+"] -],[ - "text", - ["text"," liveCount("], - ["variable.parameter.function.kotlin","i"], - ["text"," "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["variable.parameter.function.kotlin","1"], - ["text",", "], - ["variable.parameter.function.kotlin","j"], - ["text",") +"] -],[ - "text", - ["text"," liveCount(i "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",", j "], - ["keyword.operator.arithmetic.kotlin","+"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",") "], - ["keyword.operator.arithmetic.kotlin","+"] -],[ - "text", - ["text"," liveCount(i, j "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",") "], - ["keyword.operator.arithmetic.kotlin","+"] -],[ - "text", - ["text"," liveCount(i, j "], - ["keyword.operator.arithmetic.kotlin","+"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",") "], - ["keyword.operator.arithmetic.kotlin","+"] -],[ - "text", - ["text"," liveCount(i "], - ["keyword.operator.arithmetic.kotlin","+"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",", j "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",") "], - ["keyword.operator.arithmetic.kotlin","+"] -],[ - "text", - ["text"," liveCount(i "], - ["keyword.operator.arithmetic.kotlin","+"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",", j) "], - ["keyword.operator.arithmetic.kotlin","+"] -],[ - "text", - ["text"," liveCount(i "], - ["keyword.operator.arithmetic.kotlin","+"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",", j "], - ["keyword.operator.arithmetic.kotlin","+"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",")"] -],[ - "text" -],[ - "text", - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," You can say field[i, j], and this function gets called"] -],[ - ["text17","text"], - ["text"," "], - ["storage.modifier.kotlin","operator"], - ["text"," "], - ["keyword.other.kotlin","fun"], - ["text"," "], - ["entity.name.function.kotlin","get"], - ["text","("], - ["variable.parameter.function.kotlin","i"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",", "], - ["variable.parameter.function.kotlin","j"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",") "], - ["keyword.operator.assignment.kotlin","="], - ["text"," live[i][j]"] -],[ - "text", - ["text","}"] -],[ - "text" -],[ - ["punctuation.definition.comment.kotlin","text"], - ["punctuation.definition.comment.kotlin","/*"], - ["comment.block.kotlin","*"] -],[ - ["punctuation.definition.comment.kotlin","text"], - ["comment.block.kotlin"," * This function takes the present state of the field"] -],[ - ["punctuation.definition.comment.kotlin","text"], - ["comment.block.kotlin"," * and returns a new field representing the next moment of time"] -],[ - "text", - ["comment.block.kotlin"," "], - ["punctuation.definition.comment.kotlin","*/"] -],[ - ["text22","text17","text17","text"], - ["keyword.other.kotlin","fun"], - ["text"," "], - ["entity.name.function.kotlin","next"], - ["text","("], - ["variable.parameter.function.kotlin","field"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," Field)"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," Field {"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," "], - ["keyword.control.kotlin","return"], - ["text"," Field(field"], - ["keyword.operator.dot.kotlin","."], - ["text","width, field"], - ["keyword.operator.dot.kotlin","."], - ["text","height) { i, j "], - ["keyword.operator.declaration.kotlin","->"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," "], - ["keyword.other.kotlin","val"], - ["text"," "], - ["entity.name.variable.kotlin","n"], - ["text"," "], - ["keyword.operator.assignment.kotlin","="], - ["text"," field"], - ["keyword.operator.dot.kotlin","."], - ["text","liveNeighbors(i, j)"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," "], - ["keyword.control.kotlin","if"], - ["text"," (field[i, j])"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," (i, j) is alive"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," n "], - ["storage.modifier.kotlin","in"], - ["text"," "], - ["constant.numeric.kotlin","2"], - ["keyword.operator.dot.kotlin",".."], - ["constant.numeric.kotlin","3"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," It remains alive iff it has 2 or 3 neighbors"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," "], - ["keyword.control.kotlin","else"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," (i, j) is dead"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," n "], - ["keyword.operator.comparison.kotlin","=="], - ["text"," "], - ["constant.numeric.kotlin","3"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," A new cell is born if there are 3 neighbors alive"] -],[ - ["text22","text17","text17","text"], - ["text"," }"] -],[ - "text", - ["text","}"] -],[ - "text" -],[ - "text", - ["punctuation.definition.comment.kotlin","/*"], - ["comment.block.kotlin","* A few colony examples here "], - ["punctuation.definition.comment.kotlin","*/"] -],[ - ["text22","text17","text17","text"], - ["keyword.other.kotlin","fun"], - ["text"," "], - ["entity.name.function.kotlin","main"], - ["text","("], - ["variable.parameter.function.kotlin","args"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," Array<"], - ["storage.type.buildin.kotlin","String"], - ["text",">) {"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," Simplistic demo"] -],[ - ["text22","text17","text17","text"], - ["text"," runGameOfLife("], - ["punctuation.definition.string.begin.kotlin","\""], - ["string.quoted.double.kotlin","***"], - ["punctuation.definition.string.end.kotlin","\""], - ["text",", "], - ["constant.numeric.kotlin","3"], - ["text",")"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," \"Star burst\""] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["text"," runGameOfLife("], - ["punctuation.definition.string.begin.kotlin","\"\"\""] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," _______"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," ___*___"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," __***__"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," ___*___"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," _______"] -],[ - ["text22","text17","text17","text"], - ["string.quoted.third.kotlin"," "], - ["punctuation.definition.string.end.kotlin","\"\"\""], - ["text",", "], - ["constant.numeric.kotlin","10"], - ["text",")"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," Stable colony"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["text"," runGameOfLife("], - ["punctuation.definition.string.begin.kotlin","\"\"\""] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," _____"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," __*__"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," _*_*_"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," __*__"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," _____"] -],[ - ["text22","text17","text17","text"], - ["string.quoted.third.kotlin"," "], - ["punctuation.definition.string.end.kotlin","\"\"\""], - ["text",", "], - ["constant.numeric.kotlin","3"], - ["text",")"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," Stable from the step 2"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["text"," runGameOfLife("], - ["punctuation.definition.string.begin.kotlin","\"\"\""] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," __**__"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," __**__"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," __**__"] -],[ - ["text22","text17","text17","text"], - ["string.quoted.third.kotlin"," "], - ["punctuation.definition.string.end.kotlin","\"\"\""], - ["text",", "], - ["constant.numeric.kotlin","3"], - ["text",")"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," Oscillating colony"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["text"," runGameOfLife("], - ["punctuation.definition.string.begin.kotlin","\"\"\""] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," __**____"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," __**____"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," ____**__"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," ____**__"] -],[ - ["text22","text17","text17","text"], - ["string.quoted.third.kotlin"," "], - ["punctuation.definition.string.end.kotlin","\"\"\""], - ["text",", "], - ["constant.numeric.kotlin","6"], - ["text",")"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," A fancier oscillating colony"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["text"," runGameOfLife("], - ["punctuation.definition.string.begin.kotlin","\"\"\""] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------------------"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------***---***---"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------------------"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -----*----*-*----*-"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -----*----*-*----*-"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -----*----*-*----*-"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------***---***---"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------------------"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------***---***---"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -----*----*-*----*-"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -----*----*-*----*-"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -----*----*-*----*-"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------------------"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------***---***---"] -],[ - ["punctuation.definition.string.begin.kotlin","text3","text3","text22","text22","text17","text17","text"], - ["string.quoted.third.kotlin"," -------------------"] -],[ - ["text22","text17","text17","text"], - ["string.quoted.third.kotlin"," "], - ["punctuation.definition.string.end.kotlin","\"\"\""], - ["text",", "], - ["constant.numeric.kotlin","10"], - ["text",")"] -],[ - "text", - ["text","}"] -],[ - "text" -],[ - "text", - ["punctuation.definition.comment.kotlin","//"], - ["comment.line.double-slash.kotlin"," UTILITIES"] -],[ - "text" -],[ - ["text22","text17","text17","text"], - ["keyword.other.kotlin","fun"], - ["text"," "], - ["entity.name.function.kotlin","runGameOfLife"], - ["text","("], - ["variable.parameter.function.kotlin","fieldText"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","String"], - ["text",", "], - ["variable.parameter.function.kotlin","steps"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","Int"], - ["text",") {"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["keyword.other.kotlin","var"], - ["text"," "], - ["entity.name.variable.kotlin","field"], - ["text"," "], - ["keyword.operator.assignment.kotlin","="], - ["text"," makeField(fieldText)"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," "], - ["keyword.control.kotlin","for"], - ["text"," (step "], - ["storage.modifier.kotlin","in"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["keyword.operator.dot.kotlin",".."], - ["text","steps) {"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," println("], - ["punctuation.definition.string.begin.kotlin","\""], - ["string.quoted.double.kotlin","Step: "], - ["variable.parameter.template.kotlin","$step"], - ["punctuation.definition.string.end.kotlin","\""], - ["text",")"] -],[ - ["text","text","text","text22","text22","text17","text17","text"], - ["text"," "], - ["keyword.control.kotlin","for"], - ["text"," (i "], - ["storage.modifier.kotlin","in"], - ["text"," "], - ["constant.numeric.kotlin","0"], - ["keyword.operator.dot.kotlin",".."], - ["text","field"], - ["keyword.operator.dot.kotlin","."], - ["text","height "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",") {"] -],[ - ["text","text","text","text","text","text22","text22","text17","text17","text"], - ["text"," "], - ["keyword.control.kotlin","for"], - ["text"," (j "], - ["storage.modifier.kotlin","in"], - ["text"," "], - ["constant.numeric.kotlin","0"], - ["keyword.operator.dot.kotlin",".."], - ["text","field"], - ["keyword.operator.dot.kotlin","."], - ["text","width "], - ["keyword.operator.arithmetic.kotlin","-"], - ["text"," "], - ["constant.numeric.kotlin","1"], - ["text",") {"] -],[ - ["text","text","text","text","text","text22","text22","text17","text17","text"], - ["text"," print("], - ["keyword.control.kotlin","if"], - ["text"," (field[i, j]) "], - ["punctuation.definition.string.begin.kotlin","\""], - ["string.quoted.double.kotlin","*"], - ["punctuation.definition.string.end.kotlin","\""], - ["text"," "], - ["keyword.control.kotlin","else"], - ["text"," "], - ["punctuation.definition.string.begin.kotlin","\""], - ["string.quoted.double.kotlin"," "], - ["punctuation.definition.string.end.kotlin","\""], - ["text",")"] -],[ - ["text","text","text","text22","text22","text17","text17","text"], - ["text"," }"] -],[ - ["text","text","text","text22","text22","text17","text17","text"], - ["text"," println("], - ["punctuation.definition.string.begin.kotlin","\""], - ["punctuation.definition.string.end.kotlin","\""], - ["text",")"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," }"] -],[ - ["text","text22","text22","text17","text17","text"], - ["text"," field "], - ["keyword.operator.assignment.kotlin","="], - ["text"," next(field)"] -],[ - ["text22","text17","text17","text"], - ["text"," }"] -],[ - "text", - ["text","}"] -],[ - "text" -],[ - ["text22","text17","text17","text"], - ["keyword.other.kotlin","fun"], - ["text"," "], - ["entity.name.function.kotlin","makeField"], - ["text","("], - ["variable.parameter.function.kotlin","s"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["storage.type.buildin.kotlin","String"], - ["text",")"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," Field {"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["keyword.other.kotlin","val"], - ["text"," "], - ["entity.name.variable.kotlin","lines"], - ["text"," "], - ["keyword.operator.assignment.kotlin","="], - ["text"," s"], - ["keyword.operator.dot.kotlin","."], - ["text","replace("], - ["punctuation.definition.string.begin.kotlin","\""], - ["string.quoted.double.kotlin"," "], - ["punctuation.definition.string.end.kotlin","\""], - ["text",", "], - ["punctuation.definition.string.begin.kotlin","\""], - ["punctuation.definition.string.end.kotlin","\""], - ["text",")"], - ["keyword.operator.dot.kotlin","."], - ["text","split("], - ["punctuation.definition.string.begin.kotlin","'"], - ["constant.character.escape.kotlin","\\n"], - ["punctuation.definition.string.end.kotlin","'"], - ["text",")"], - ["keyword.operator.dot.kotlin","."], - ["text","filter({ it"], - ["keyword.operator.dot.kotlin","."], - ["text","isNotEmpty() })"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["keyword.other.kotlin","val"], - ["text"," "], - ["entity.name.variable.kotlin","longestLine"], - ["text"," "], - ["keyword.operator.assignment.kotlin","="], - ["text"," lines"], - ["keyword.operator.dot.kotlin","."], - ["text","toList()"], - ["keyword.operator.dot.kotlin","."], - ["text","maxBy { it"], - ["keyword.operator.dot.kotlin","."], - ["text","length } ?"], - ["keyword.operator.declaration.kotlin",":"], - ["text"," "], - ["punctuation.definition.string.begin.kotlin","\""], - ["punctuation.definition.string.end.kotlin","\""] -],[ - ["text22","text17","text17","text"] -],[ - ["text22","text17","text17","text"], - ["text"," "], - ["keyword.control.kotlin","return"], - ["text"," Field(longestLine"], - ["keyword.operator.dot.kotlin","."], - ["text","length, lines"], - ["keyword.operator.dot.kotlin","."], - ["text","size) { i, j "], - ["keyword.operator.declaration.kotlin","->"], - ["text"," lines[i][j] "], - ["keyword.operator.comparison.kotlin","=="], - ["text"," "], - ["punctuation.definition.string.begin.kotlin","'"], - ["string.quoted.single.kotlin","*"], - ["punctuation.definition.string.end.kotlin","'"], - ["text"," }"] -],[ - "text", - ["text","}"] -],[ - "text" -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_liquid.json b/lib/ace/mode/_test/tokens_liquid.json deleted file mode 100644 index 30d003cb6aa..00000000000 --- a/lib/ace/mode/_test/tokens_liquid.json +++ /dev/null @@ -1,551 +0,0 @@ -[[ - "start", - ["text.xml","The following examples can be found in full at http://liquidmarkup.org/"] -],[ - "start" -],[ - "start", - ["text.xml","Liquid is an extraction from the e-commerce system Shopify."] -],[ - "start", - ["text.xml","Shopify powers many thousands of e-commerce stores which all call for unique designs."] -],[ - "start", - ["text.xml","For this we developed Liquid which allows our customers complete design freedom while"] -],[ - "start", - ["text.xml","maintaining the integrity of our servers."] -],[ - "start" -],[ - "start", - ["text.xml","Liquid has been in production use since June 2006 and is now used by many other"] -],[ - "start", - ["text.xml","hosted web applications."] -],[ - "start" -],[ - "start", - ["text.xml","It was developed for usage in Ruby on Rails web applications and integrates seamlessly"] -],[ - "start", - ["text.xml","as a plugin but it also works excellently as a stand alone library."] -],[ - "start" -],[ - "start", - ["text.xml","Here's what it looks like:"] -],[ - "start" -],[ - "start", - ["text.xml"," "], - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","ul"], - ["text.tag-whitespace.xml"," "], - ["entity.other.attribute-name.xml","id"], - ["keyword.operator.attribute-equals.xml","="], - ["string.attribute-value.xml","\"products\""], - ["meta.tag.punctuation.tag-close.xml",">"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","for"], - ["text"," "], - ["identifier","product"], - ["text"," "], - ["keyword","in"], - ["text"," "], - ["identifier","products"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," "], - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","li"], - ["meta.tag.punctuation.tag-close.xml",">"] -],[ - "start", - ["text.xml"," "], - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","h2"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["variable","{{"], - ["text"," "], - ["identifier","product"], - ["text","."], - ["identifier","title"], - ["text"," "], - ["variable","}}"], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["text.xml"," Only "], - ["variable","{{"], - ["text"," "], - ["identifier","product"], - ["text","."], - ["identifier","price"], - ["text"," | "], - ["identifier","format_as_money"], - ["text"," "], - ["variable","}}"] -],[ - "start" -],[ - "start", - ["text.xml"," "], - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["variable","{{"], - ["text"," "], - ["identifier","product"], - ["text","."], - ["identifier","description"], - ["text"," | "], - ["identifier","prettyprint"], - ["text"," | "], - ["support.function","truncate"], - ["text",": "], - ["constant.numeric","200"], - ["text"," "], - ["variable","}}"], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start" -],[ - "start", - ["text.xml"," "], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","endfor"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," "], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start" -],[ - "start" -],[ - "start", - ["text.xml","Some more features include:"] -],[ - "start" -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","h2"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml","Filters"], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml"," The word \"tobi\" in uppercase: "], - ["variable","{{"], - ["text"," "], - ["string","'tobi'"], - ["text"," | "], - ["support.function","upcase"], - ["text"," "], - ["variable","}}"], - ["text.xml"," "], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml","The word \"tobi\" has "], - ["variable","{{"], - ["text"," "], - ["string","'tobi'"], - ["text"," | "], - ["support.function","size"], - ["text"," "], - ["variable","}}"], - ["text.xml"," letters! "], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml","Change \"Hello world\" to \"Hi world\": "], - ["variable","{{"], - ["text"," "], - ["string","'Hello world'"], - ["text"," | "], - ["support.function","replace"], - ["text",": "], - ["string","'Hello'"], - ["text",", "], - ["string","'Hi'"], - ["text"," "], - ["variable","}}"], - ["text.xml"," "], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml","The date today is "], - ["variable","{{"], - ["text"," "], - ["string","'now'"], - ["text"," | "], - ["support.function","date"], - ["text",": "], - ["string","\"%Y %b %d\""], - ["text"," "], - ["variable","}}"], - ["text.xml"," "], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start" -],[ - "start" -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","h2"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml","If"], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","if"], - ["text"," "], - ["identifier","user"], - ["text","."], - ["identifier","name"], - ["text"," "], - ["keyword.operator","=="], - ["text"," "], - ["string","'tobi'"], - ["text"," "], - ["identifier","or"], - ["text"," "], - ["identifier","user"], - ["text","."], - ["identifier","name"], - ["text"," "], - ["keyword.operator","=="], - ["text"," "], - ["string","'marc'"], - ["text"," "], - ["variable","%}"], - ["text.xml"," "] -],[ - "start", - ["text.xml"," hi marc or tobi"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","endif"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start" -],[ - "start" -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","h2"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml","Case"], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","case"], - ["text"," "], - ["identifier","template"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","when"], - ["text"," "], - ["string","'index'"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," Welcome"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","when"], - ["text"," "], - ["string","'product'"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," "], - ["variable","{{"], - ["text"," "], - ["identifier","product"], - ["text","."], - ["identifier","vendor"], - ["text"," | "], - ["identifier","link_to_vendor"], - ["text"," "], - ["variable","}}"], - ["text.xml"," / "], - ["variable","{{"], - ["text"," "], - ["identifier","product"], - ["text","."], - ["identifier","title"], - ["text"," "], - ["variable","}}"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","else"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," "], - ["variable","{{"], - ["text"," "], - ["identifier","page_title"], - ["text"," "], - ["variable","}}"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","endcase"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start" -],[ - "start" -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","h2"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml","For Loops"], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","for"], - ["text"," "], - ["identifier","item"], - ["text"," "], - ["keyword","in"], - ["text"," "], - ["identifier","array"], - ["text"," "], - ["variable","%}"], - ["text.xml"," "] -],[ - "start", - ["text.xml"," "], - ["variable","{{"], - ["text"," "], - ["identifier","item"], - ["text"," "], - ["variable","}}"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","endfor"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start" -],[ - "start" -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","h2"], - ["meta.tag.punctuation.tag-close.xml",">"], - ["text.xml","Tables"], - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start", - ["meta.tag.punctuation.tag-open.xml","<"], - ["meta.tag.tag-name.xml","p"], - ["meta.tag.punctuation.tag-close.xml",">"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","tablerow"], - ["text"," "], - ["identifier","item"], - ["text"," "], - ["keyword","in"], - ["text"," "], - ["identifier","items"], - ["text"," "], - ["identifier","cols"], - ["text",": "], - ["constant.numeric","3"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","if"], - ["text"," "], - ["variable.language","tablerowloop"], - ["text","."], - ["identifier","col_first"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," First column: "], - ["variable","{{"], - ["text"," "], - ["identifier","item"], - ["text","."], - ["identifier","variable"], - ["text"," "], - ["variable","}}"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","else"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," Different column: "], - ["variable","{{"], - ["text"," "], - ["identifier","item"], - ["text","."], - ["identifier","variable"], - ["text"," "], - ["variable","}}"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","endif"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["text.xml"," "], - ["variable","{%"], - ["text"," "], - ["keyword","endtablerow"], - ["text"," "], - ["variable","%}"] -],[ - "start", - ["meta.tag.punctuation.end-tag-open.xml",""] -],[ - "start" -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_lucene.json b/lib/ace/mode/_test/tokens_lucene.json deleted file mode 100644 index 1f6d2985e20..00000000000 --- a/lib/ace/mode/_test/tokens_lucene.json +++ /dev/null @@ -1,92 +0,0 @@ -[[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["keyword.operator","AND"], - ["text"," as keyword"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["keyword.operator","OR"], - ["text"," as keyword"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["keyword.operator","NOT"], - ["text"," as keyword"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["string","\"hello this is dog\""], - ["text"," as string"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["constant.character.negation","-"], - ["string","\"hello this is dog\""], - ["text"," as negation with string"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["constant.character.proximity","~100"], - ["text"," as text with proximity"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["string","\"hello this is dog\""], - ["constant.character.proximity","~100"], - ["text"," as string with proximity"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["keyword","raw:"], - ["string","\"hello this is dog\""], - ["text"," as keyword"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["keyword","raw:"], - ["text","foo as\"keyword'"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["string","\"(\""], - ["text"," as opening parenthesis"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises "], - ["string","\")\""], - ["text"," as closing parenthesis"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises foo"], - ["constant.character.asterisk","*"], - ["text"," as text with asterisk"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises foo"], - ["constant.character.interro","?"], - ["text"," as text with interro"] -],[ - "start", - ["keyword","test:"], - ["text"," recognises single word as text"] -],[ - "start", - ["text"," foo"] -],[ - "start", - ["text"," "] -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_pascal.json b/lib/ace/mode/_test/tokens_pascal.json deleted file mode 100644 index 22c1f0c43e5..00000000000 --- a/lib/ace/mode/_test/tokens_pascal.json +++ /dev/null @@ -1,297 +0,0 @@ -[[ - "punctuation.definition.comment.pascal", - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one","****************************************************************************"] -],[ - "punctuation.definition.comment.pascal", - ["comment.block.pascal.one"," * A simple bubble sort program. Reads integers, one per line, and prints *"] -],[ - "punctuation.definition.comment.pascal", - ["comment.block.pascal.one"," * them out in sorted order. Blows up if there are more than 49. *"] -],[ - "start", - ["comment.block.pascal.one"," ****************************************************************************"], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["keyword.control.pascal","PROGRAM"], - ["text"," Sort(input"], - ["keyword.operator",","], - ["text"," output)"], - ["keyword.operator",";"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","CONST"] -],[ - "start", - ["text"," "], - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one"," Max array size. "], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["text"," MaxElts "], - ["keyword.operator","="], - ["text"," "], - ["constant.numeric.pascal","50"], - ["keyword.operator",";"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","TYPE"], - ["text"," "] -],[ - "start", - ["text"," "], - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one"," Type of the element array. "], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["text"," IntArrType "], - ["keyword.operator","="], - ["text"," "], - ["keyword.control.pascal","ARRAY"], - ["text"," ["], - ["constant.numeric.pascal","1"], - ["text","..MaxElts] "], - ["keyword.control.pascal","OF"], - ["text"," Integer"], - ["keyword.operator",";"] -],[ - "start" -],[ - "start", - ["text"," "], - ["keyword.control.pascal","VAR"] -],[ - "start", - ["text"," "], - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one"," Indexes, exchange temp, array size. "], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["text"," i"], - ["keyword.operator",","], - ["text"," j"], - ["keyword.operator",","], - ["text"," tmp"], - ["keyword.operator",","], - ["text"," size: integer"], - ["keyword.operator",";"] -],[ - "start" -],[ - "start", - ["text"," "], - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one"," Array of ints "], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["text"," arr: IntArrType"], - ["keyword.operator",";"] -],[ - "start" -],[ - "start", - ["text"," "], - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one"," Read in the integers. "], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["text"," "], - ["variable.pascal","PROCEDURE"], - ["text"," "], - ["storage.type.function.pascal","ReadArr"], - ["text","("], - ["keyword.control.pascal","VAR"], - ["text"," size: Integer"], - ["keyword.operator",";"], - ["text"," "], - ["keyword.control.pascal","VAR"], - ["text"," a: IntArrType)"], - ["keyword.operator",";"], - ["text"," "] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","BEGIN"] -],[ - "start", - ["text"," size "], - ["keyword.operator",":="], - ["text"," "], - ["constant.numeric.pascal","1"], - ["keyword.operator",";"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","WHILE"], - ["text"," "], - ["keyword.control.pascal","NOT"], - ["text"," eof "], - ["keyword.control.pascal","DO"], - ["text"," "], - ["keyword.control.pascal","BEGIN"] -],[ - "start", - ["text"," readln(a[size])"], - ["keyword.operator",";"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","IF"], - ["text"," "], - ["keyword.control.pascal","NOT"], - ["text"," eof "], - ["keyword.control.pascal","THEN"], - ["text"," "] -],[ - "start", - ["text"," size "], - ["keyword.operator",":="], - ["text"," size "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric.pascal","1"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","END"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","END"], - ["keyword.operator",";"] -],[ - "start" -],[ - "start", - ["text"," "], - ["keyword.control.pascal","BEGIN"] -],[ - "start", - ["text"," "], - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one"," Read "], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["text"," ReadArr(size"], - ["keyword.operator",","], - ["text"," arr)"], - ["keyword.operator",";"] -],[ - "start" -],[ - "start", - ["text"," "], - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one"," Sort using bubble sort. "], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","FOR"], - ["text"," i "], - ["keyword.operator",":="], - ["text"," size "], - ["keyword.operator","-"], - ["text"," "], - ["constant.numeric.pascal","1"], - ["text"," DOWNTO "], - ["constant.numeric.pascal","1"], - ["text"," "], - ["keyword.control.pascal","DO"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","FOR"], - ["text"," j "], - ["keyword.operator",":="], - ["text"," "], - ["constant.numeric.pascal","1"], - ["text"," "], - ["keyword.control.pascal","TO"], - ["text"," i "], - ["keyword.control.pascal","DO"], - ["text"," "] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","IF"], - ["text"," arr[j] > arr[j "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric.pascal","1"], - ["text","] "], - ["keyword.control.pascal","THEN"], - ["text"," "], - ["keyword.control.pascal","BEGIN"] -],[ - "start", - ["text"," tmp "], - ["keyword.operator",":="], - ["text"," arr[j]"], - ["keyword.operator",";"] -],[ - "start", - ["text"," arr[j] "], - ["keyword.operator",":="], - ["text"," arr[j "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric.pascal","1"], - ["text","]"], - ["keyword.operator",";"] -],[ - "start", - ["text"," arr[j "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric.pascal","1"], - ["text","] "], - ["keyword.operator",":="], - ["text"," tmp"], - ["keyword.operator",";"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","END"], - ["keyword.operator",";"] -],[ - "start" -],[ - "start", - ["text"," "], - ["punctuation.definition.comment.pascal","(*"], - ["comment.block.pascal.one"," Print. "], - ["punctuation.definition.comment.pascal","*)"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","FOR"], - ["text"," i "], - ["keyword.operator",":="], - ["text"," "], - ["constant.numeric.pascal","1"], - ["text"," "], - ["keyword.control.pascal","TO"], - ["text"," size "], - ["keyword.control.pascal","DO"] -],[ - "start", - ["text"," writeln(arr[i])"] -],[ - "start", - ["text"," "], - ["keyword.control.pascal","END"], - ["text","."] -],[ - "start", - ["text"," "] -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_powershell.json b/lib/ace/mode/_test/tokens_powershell.json deleted file mode 100644 index 43b77db4639..00000000000 --- a/lib/ace/mode/_test/tokens_powershell.json +++ /dev/null @@ -1,184 +0,0 @@ -[[ - "start", - ["comment","# This is a simple comment"] -],[ - "start", - ["keyword","function"], - ["text"," "], - ["identifier","Hello"], - ["lparen","("], - ["variable.instance","$name"], - ["rparen",")"], - ["text"," "], - ["lparen","{"] -],[ - "start", - ["text"," "], - ["identifier","Write-host"], - ["text"," "], - ["string","\"Hello $name\""] -],[ - "start", - ["rparen","}"] -],[ - "start" -],[ - "start", - ["keyword","function"], - ["text"," "], - ["identifier","add"], - ["lparen","("], - ["variable.instance","$left"], - ["text",", "], - ["variable.instance","$right"], - ["keyword.operator","="], - ["constant.numeric","4"], - ["rparen",")"], - ["text"," "], - ["lparen","{"] -],[ - "start", - ["text"," "], - ["keyword","if"], - ["text"," "], - ["lparen","("], - ["variable.instance","$right"], - ["text"," "], - ["keyword.operator","-ne"], - ["text"," "], - ["constant.numeric","4"], - ["rparen",")"], - ["text"," "], - ["lparen","{"] -],[ - "start", - ["text"," "], - ["keyword","return"], - ["text"," "], - ["variable.instance","$left"] -],[ - "start", - ["text"," "], - ["rparen","}"], - ["text"," "], - ["keyword","elseif"], - ["text"," "], - ["lparen","("], - ["variable.instance","$left"], - ["text"," "], - ["keyword.operator","-eq"], - ["text"," "], - ["constant.language","$null"], - ["text"," "], - ["keyword.operator","-and"], - ["text"," "], - ["variable.instance","$right"], - ["text"," "], - ["keyword.operator","-eq"], - ["text"," "], - ["constant.numeric","2"], - ["rparen",")"], - ["text"," "], - ["lparen","{"] -],[ - "start", - ["text"," "], - ["keyword","return"], - ["text"," "], - ["constant.numeric","3"] -],[ - "start", - ["text"," "], - ["rparen","}"], - ["text"," "], - ["keyword","else"], - ["text"," "], - ["lparen","{"] -],[ - "start", - ["text"," "], - ["keyword","return"], - ["text"," "], - ["constant.numeric","2"] -],[ - "start", - ["text"," "], - ["rparen","}"] -],[ - "start", - ["rparen","}"] -],[ - "start" -],[ - "start", - ["variable.instance","$number"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["constant.numeric","1"], - ["text"," "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric","2"], - ["text",";"] -],[ - "start", - ["variable.instance","$number"], - ["text"," "], - ["keyword.operator","+="], - ["text"," "], - ["constant.numeric","3"] -],[ - "start" -],[ - "start", - ["support.function","Write-Host"], - ["text"," "], - ["identifier","Hello"], - ["text"," "], - ["keyword.operator","-"], - ["identifier","name"], - ["text"," "], - ["string","\"World\""] -],[ - "start" -],[ - "start", - ["variable.instance","$an_array"], - ["text"," "], - ["keyword.operator","="], - ["text"," @"], - ["lparen","("], - ["constant.numeric","1"], - ["text",", "], - ["constant.numeric","2"], - ["text",", "], - ["constant.numeric","3"], - ["rparen",")"] -],[ - "start", - ["variable.instance","$a_hash"], - ["text"," "], - ["keyword.operator","="], - ["text"," @"], - ["lparen","{"], - ["string","\"something\""], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["string","\"something else\""], - ["rparen","}"] -],[ - "start" -],[ - "start", - ["keyword.operator","&"], - ["text"," "], - ["identifier","notepad"], - ["text"," .\\"], - ["identifier","readme"], - ["text","."], - ["identifier","md"] -],[ - "start" -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_python.json b/lib/ace/mode/_test/tokens_python.json deleted file mode 100644 index 293c8ff2fc9..00000000000 --- a/lib/ace/mode/_test/tokens_python.json +++ /dev/null @@ -1,152 +0,0 @@ -[[ - "start", - ["comment","#!/usr/local/bin/python"] -],[ - "start" -],[ - "start", - ["keyword","import"], - ["text"," "], - ["identifier","string"], - ["text",", "], - ["identifier","sys"] -],[ - "start" -],[ - "start", - ["comment","# If no arguments were given, print a helpful message"] -],[ - "start", - ["keyword","if"], - ["text"," "], - ["support.function","len"], - ["paren.lparen","("], - ["identifier","sys"], - ["text","."], - ["identifier","argv"], - ["paren.rparen",")"], - ["keyword.operator","=="], - ["constant.numeric","1"], - ["text",":"] -],[ - "qstring3", - ["text"," "], - ["keyword","print"], - ["text"," "], - ["string","'''Usage:"] -],[ - "start", - ["string","celsius temp1 temp2 ...'''"] -],[ - "start", - ["text"," "], - ["identifier","sys"], - ["text","."], - ["identifier","exit"], - ["paren.lparen","("], - ["constant.numeric","0"], - ["paren.rparen",")"] -],[ - "start" -],[ - "start", - ["comment","# Loop over the arguments"] -],[ - "start", - ["keyword","for"], - ["text"," "], - ["identifier","i"], - ["text"," "], - ["keyword","in"], - ["text"," "], - ["identifier","sys"], - ["text","."], - ["identifier","argv"], - ["paren.lparen","["], - ["constant.numeric","1"], - ["text",":"], - ["paren.rparen","]"], - ["text",":"] -],[ - "start", - ["text"," "], - ["keyword","try"], - ["text",":"] -],[ - "start", - ["text"," "], - ["identifier","fahrenheit"], - ["keyword.operator","="], - ["support.function","float"], - ["paren.lparen","("], - ["identifier","string"], - ["text","."], - ["identifier","atoi"], - ["paren.lparen","("], - ["identifier","i"], - ["paren.rparen","))"] -],[ - "start", - ["text"," "], - ["keyword","except"], - ["text"," "], - ["identifier","string"], - ["text","."], - ["identifier","atoi_error"], - ["text",":"] -],[ - "start", - ["text"," "], - ["keyword","print"], - ["text"," "], - ["support.function","repr"], - ["paren.lparen","("], - ["identifier","i"], - ["paren.rparen",")"], - ["text",", "], - ["string","\"not a numeric value\""] -],[ - "start", - ["text"," "], - ["keyword","else"], - ["text",":"] -],[ - "start", - ["text"," "], - ["identifier","celsius"], - ["keyword.operator","="], - ["paren.lparen","("], - ["identifier","fahrenheit"], - ["keyword.operator","-"], - ["constant.numeric","32"], - ["paren.rparen",")"], - ["keyword.operator","*"], - ["constant.numeric","5.0"], - ["keyword.operator","/"], - ["constant.numeric","9.0"] -],[ - "start", - ["text"," "], - ["keyword","print"], - ["text"," "], - ["string","'%i"], - ["constant.language.escape","\\260"], - ["string","F = %i"], - ["constant.language.escape","\\260"], - ["string","C'"], - ["text"," "], - ["keyword.operator","%"], - ["text"," "], - ["paren.lparen","("], - ["support.function","int"], - ["paren.lparen","("], - ["identifier","fahrenheit"], - ["paren.rparen",")"], - ["text",", "], - ["support.function","int"], - ["paren.lparen","("], - ["identifier","celsius"], - ["keyword.operator","+"], - ["constant.numeric",".5"], - ["paren.rparen","))"] -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_ruby.json b/lib/ace/mode/_test/tokens_ruby.json deleted file mode 100644 index f9991e9cec4..00000000000 --- a/lib/ace/mode/_test/tokens_ruby.json +++ /dev/null @@ -1,242 +0,0 @@ -[[ - "start", - ["text"," "], - ["comment","#test: symbol tokenizer"] -],[ - "start", - ["text"," "], - ["paren.lparen","["], - ["constant.other.symbol.ruby",":@thing"], - ["text",", "], - ["constant.other.symbol.ruby",":$thing"], - ["text",", "], - ["constant.other.symbol.ruby",":_thing"], - ["text",", "], - ["constant.other.symbol.ruby",":thing"], - ["text",", "], - ["constant.other.symbol.ruby",":Thing"], - ["text",", "], - ["constant.other.symbol.ruby",":thing1"], - ["text",", "], - ["constant.other.symbol.ruby",":thing_a"], - ["text",","] -],[ - "start", - ["text"," "], - ["constant.other.symbol.ruby",":THING"], - ["text",", "], - ["constant.other.symbol.ruby",":thing!"], - ["text",", "], - ["constant.other.symbol.ruby",":thing="], - ["text",", "], - ["constant.other.symbol.ruby",":thing?"], - ["text",", "], - ["constant.other.symbol.ruby",":t?"], - ["text",","] -],[ - "start", - ["text"," :, :@, :"], - ["keyword.operator","$"], - ["text",", :"], - ["constant.numeric","1"], - ["text",", :1"], - ["identifier","thing"], - ["text",", "], - ["constant.other.symbol.ruby",":th?"], - ["identifier","ing"], - ["text",", "], - ["constant.other.symbol.ruby",":thi="], - ["identifier","ng"], - ["text",", :1"], - ["identifier","thing"], - ["text",","] -],[ - "start", - ["text"," "], - ["constant.other.symbol.ruby",":th!"], - ["identifier","ing"], - ["text",", "], - ["constant.other.symbol.ruby",":thing"], - ["comment","#"] -],[ - "start", - ["text"," "], - ["paren.rparen","]"] -],[ - "start" -],[ - "start", - ["text"," "], - ["comment","#test: namespaces aren't symbols\" : function() {"] -],[ - "start", - ["text"," "], - ["support.class","Namespaced"], - ["text","::"], - ["support.class","Class"] -],[ - "start", - ["text"," "], - ["comment","#test: hex tokenizer "] -],[ - "start", - ["text"," "], - ["constant.numeric","0x9a"], - ["text",", "], - ["constant.numeric","0XA1"], - ["text",", "], - ["constant.numeric","0x9_a"], - ["text",", 0"], - ["identifier","x"], - ["text",", 0"], - ["identifier","x_9a"], - ["text",", 0"], - ["identifier","x9a_"], - ["text",","] -],[ - "start", - ["text"," "], - ["comment","#test: float tokenizer"] -],[ - "start", - ["text"," "], - ["paren.lparen","["], - ["constant.numeric","1"], - ["text",", "], - ["constant.numeric","+1"], - ["text",", "], - ["constant.numeric","-1"], - ["text",", "], - ["constant.numeric","12_345"], - ["text",", "], - ["constant.numeric","0.000_1"], - ["text",","] -],[ - "start", - ["text"," "], - ["identifier","_"], - ["text",", "], - ["constant.numeric","3_1"], - ["text",", "], - ["constant.numeric","1_2"], - ["text",", 1"], - ["identifier","_"], - ["text","."], - ["constant.numeric","0"], - ["text",", "], - ["constant.numeric","0"], - ["text","."], - ["identifier","_1"], - ["paren.rparen","]"], - ["text",";"] -],[ - "start", - ["text"," "] -],[ - "start", - ["paren.lparen","{"], - ["constant.other.symbol.ruby",":id"], - ["text"," "], - ["punctuation.separator.key-value","=>"], - ["text"," "], - ["string.character","?\""], - ["text",", "], - ["constant.other.symbol.ruby",":key"], - ["text"," "], - ["punctuation.separator.key-value","=>"], - ["text"," "], - ["string.start","\""], - ["string","value"], - ["string.end","\""], - ["text",", "], - ["identifier","anotherKey"], - ["text",": "], - ["paren.lparen","["], - ["identifier","x"], - ["text",", "], - ["identifier","y"], - ["text","?"], - ["paren.rparen","]}"] -],[ - "start" -],[ - "comment", - ["comment","=begin"] -],[ - "start", - ["comment","=end"] -],[ - "start" -],[ - "comment", - ["comment","=begin x"] -],[ - "comment", - ["comment","=end-"] -],[ - "start", - ["comment","=end x"] -],[ - "start" -],[ - ["heredoc","FOO","heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"], - ["text"," "], - ["identifier","herDocs"], - ["text"," "], - ["keyword.operator","="], - ["text"," "], - ["paren.lparen","["], - ["constant","<<"], - ["string","'"], - ["support.class","FOO"], - ["string","'"], - ["text",", "], - ["constant","<<"], - ["string",""], - ["support.class","BAR"], - ["string",""], - ["text",", "], - ["constant","<<-"], - ["string",""], - ["support.class","BAZ"], - ["string",""], - ["text",", "], - ["constant","<<-"], - ["string","`"], - ["support.class","EXEC"], - ["string","`"], - ["paren.rparen","]"], - ["text"," "], - ["comment","#comment"] -],[ - ["heredoc","FOO","heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"], - ["string"," FOO #{literal}"] -],[ - ["heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"], - ["support.class","FOO"] -],[ - ["heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"], - ["string"," BAR #{fact(10)}"] -],[ - ["indentedHeredoc","BAZ","indentedHeredoc","EXEC"], - ["support.class","BAR"] -],[ - ["indentedHeredoc","BAZ","indentedHeredoc","EXEC"], - ["string"," BAZ indented"] -],[ - ["indentedHeredoc","EXEC"], - ["string"," "], - ["support.class","BAZ"] -],[ - ["indentedHeredoc","EXEC"], - ["string"," echo hi"] -],[ - "start", - ["string"," "], - ["support.class","EXEC"] -],[ - "start", - ["support.function","puts"], - ["text"," "], - ["identifier","herDocs"] -]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_rust.json b/lib/ace/mode/_test/tokens_rust.json deleted file mode 100644 index 68add464f9d..00000000000 --- a/lib/ace/mode/_test/tokens_rust.json +++ /dev/null @@ -1,299 +0,0 @@ -[[ - "start", - ["keyword.source.rust","use"], - ["text"," "], - ["support.constant","core::rand::"], - ["text","RngUtil"], - ["punctuation.operator",";"] -],[ - "start" -],[ - "start", - ["keyword.source.rust","fn"], - ["text"," "], - ["entity.name.function.source.rust","main"], - ["paren.lparen","("], - ["paren.rparen",")"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," "], - ["keyword.source.rust","for"], - ["text"," "], - ["paren.lparen","["], - ["string.quoted.double.source.rust","\"Alice\""], - ["punctuation.operator",","], - ["text"," "], - ["string.quoted.double.source.rust","\"Bob\""], - ["punctuation.operator",","], - ["text"," "], - ["string.quoted.double.source.rust","\"Carol\""], - ["paren.rparen","]"], - ["punctuation.operator","."], - ["text","each "], - ["keyword.operator","|&"], - ["text","name"], - ["keyword.operator","|"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," "], - ["keyword.source.rust","do"], - ["text"," spawn "], - ["paren.lparen","{"] -],[ - "start", - ["text"," "], - ["keyword.source.rust","let"], - ["text"," v "], - ["keyword.operator","="], - ["text"," "], - ["support.constant","rand::"], - ["text","Rng"], - ["paren.lparen","("], - ["paren.rparen",")"], - ["punctuation.operator","."], - ["text","shuffle"], - ["paren.lparen","(["], - ["constant.numeric.source.rust","1"], - ["punctuation.operator",","], - ["text"," "], - ["constant.numeric.source.rust","2"], - ["punctuation.operator",","], - ["text"," "], - ["constant.numeric.source.rust","3"], - ["paren.rparen","])"], - ["punctuation.operator",";"] -],[ - "start", - ["text"," "], - ["keyword.source.rust","for"], - ["text"," v"], - ["punctuation.operator","."], - ["text","each "], - ["keyword.operator","|&"], - ["text","num"], - ["keyword.operator","|"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," print"], - ["paren.lparen","("], - ["text","fmt"], - ["keyword.operator","!"], - ["paren.lparen","("], - ["string.quoted.double.source.rust","\"%s says: '%d'"], - ["constant.character.escape.source.rust","\\n\\\\"], - ["string.quoted.double.source.rust","\""], - ["punctuation.operator",","], - ["text"," name"], - ["punctuation.operator",","], - ["text"," num "], - ["keyword.operator","+"], - ["text"," "], - ["constant.numeric.source.rust","1"], - ["paren.rparen","))"] -],[ - "start", - ["text"," "], - ["paren.rparen","}"] -],[ - "start", - ["text"," "], - ["paren.rparen","}"] -],[ - "start", - ["text"," "], - ["paren.rparen","}"] -],[ - "start" -],[ - "start", - ["keyword.source.rust","let"], - ["text"," _ "], - ["punctuation.operator",":"], - ["storage.type.source.rust","i128"], - ["keyword.operator","=-"], - ["constant.numeric.source.rust","42i128"], - ["punctuation.operator",";"] -],[ - "start", - ["keyword.source.rust","let"], - ["text"," _ "], - ["punctuation.operator",":"], - ["storage.type.source.rust","u128"], - ["keyword.operator","="], - ["constant.numeric.source.rust","42u128"], - ["punctuation.operator",";"] -],[ - "start", - ["paren.rparen","}"] -],[ - "start" -],[ - ["comment","comment"], - ["comment.start.block.source.rust","/*"], - ["comment.block.source.rust"," nested "], - ["comment.start.block.source.rust","/*"], - ["comment.block.source.rust"," "] -],[ - "start", - ["comment.block.source.rust"," comments "], - ["comment.end.block.source.rust","*/"], - ["comment.block.source.rust"," "], - ["comment.end.block.source.rust","*/"] -],[ - "start" -],[ - "start", - ["keyword.source.rust","fn"], - ["text"," "], - ["entity.name.function.source.rust","map"], - ["keyword.operator","<"], - ["text","T"], - ["punctuation.operator",","], - ["text"," U"], - ["keyword.operator",">"], - ["paren.lparen","("], - ["text","vector"], - ["punctuation.operator",":"], - ["text"," "], - ["keyword.operator","&"], - ["paren.lparen","["], - ["text","T"], - ["paren.rparen","]"], - ["punctuation.operator",","], - ["text"," function"], - ["punctuation.operator",":"], - ["text"," "], - ["keyword.operator","&"], - ["text","fn"], - ["paren.lparen","("], - ["text","v"], - ["punctuation.operator",":"], - ["text"," "], - ["keyword.operator","&"], - ["text","T"], - ["paren.rparen",")"], - ["text"," "], - ["keyword.operator","->"], - ["text"," U"], - ["paren.rparen",")"], - ["text"," "], - ["keyword.operator","->"], - ["text"," ~"], - ["paren.lparen","["], - ["text","U"], - ["paren.rparen","]"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," "], - ["keyword.source.rust","let"], - ["text"," "], - ["keyword.source.rust","mut"], - ["text"," accumulator "], - ["keyword.operator","="], - ["text"," ~"], - ["paren.lparen","["], - ["paren.rparen","]"], - ["punctuation.operator",";"] -],[ - "start", - ["text"," "], - ["keyword.source.rust","for"], - ["text"," "], - ["support.constant","vec::"], - ["text","each"], - ["paren.lparen","("], - ["text","vector"], - ["paren.rparen",")"], - ["text"," "], - ["keyword.operator","|"], - ["text","element"], - ["keyword.operator","|"], - ["text"," "], - ["paren.lparen","{"] -],[ - "start", - ["text"," accumulator"], - ["punctuation.operator","."], - ["text","push"], - ["paren.lparen","("], - ["text","function"], - ["paren.lparen","("], - ["text","element"], - ["paren.rparen","))"], - ["punctuation.operator",";"] -],[ - "start", - ["text"," "], - ["paren.rparen","}"] -],[ - "start", - ["text"," "], - ["keyword.source.rust","return"], - ["text"," accumulator"], - ["punctuation.operator",";"] -],[ - "start", - ["paren.rparen","}"] -],[ - "start" -],[ - "start" -],[ - "start", - ["comment.line.double-dash.source.rust","// numbers"] -],[ - "start", - ["constant.numeric.source.rust","14E-111_f64"], - ["punctuation.operator",";"], - ["text"," "], - ["constant.numeric.source.rust","45isize"], - ["text"," "], - ["constant.numeric.source.rust","0x1i32"], - ["text"," "], - ["constant.numeric.source.rust","0o777u32"], - ["text"," "], - ["constant.numeric.source.rust","0b01"], - ["text"," "], - ["constant.numeric.source.rust","14f32"], - ["text"," "], - ["constant.numeric.source.rust","1_2.78f32"], - ["text"," "], - ["constant.numeric.source.rust","1_2.3E+7f32"] -],[ - "start" -],[ - "start", - ["comment.line.double-dash.source.rust","// not numbers"] -],[ - "start", - ["constant.numeric.source.rust","14"], - ["punctuation.operator","."], - ["text","_E"], - ["keyword.operator","-"], - ["constant.numeric.source.rust","111_f64"], - ["punctuation.operator",";"], - ["text","0xi32"], - ["punctuation.operator",";"], - ["text","0b777u"] -],[ - "start", - ["text","foo1"], - ["punctuation.operator",";"], - ["text","foo1u32"], - ["punctuation.operator",";"], - ["text","foo1f32"], - ["punctuation.operator",";"], - ["text","foo0xF"], - ["punctuation.operator",";"], - ["text","foo1"], - ["punctuation.operator","."], - ["constant.numeric.source.rust","0"] -]] diff --git a/lib/ace/mode/_test/tokens_yaml.json b/lib/ace/mode/_test/tokens_yaml.json deleted file mode 100644 index 0d2acadc4b9..00000000000 --- a/lib/ace/mode/_test/tokens_yaml.json +++ /dev/null @@ -1,167 +0,0 @@ -[[ - "start", - ["comment","# This sample document was taken from wikipedia:"] -],[ - "start", - ["comment","# http://en.wikipedia.org/wiki/YAML#Sample_document"] -],[ - "start", - ["list.markup","---"] -],[ - "start", - ["meta.tag","receipt"], - ["keyword",":"], - ["text"," Oz-Ware Purchase Invoice"] -],[ - "start", - ["meta.tag","date"], - ["keyword",":"], - ["text"," 2007-08-06"] -],[ - "start", - ["meta.tag","customer"], - ["keyword",":"] -],[ - "start", - ["meta.tag"," given"], - ["keyword",":"], - ["text"," Dorothy"] -],[ - "start", - ["meta.tag"," family"], - ["keyword",":"], - ["text"," Gale"] -],[ - "start" -],[ - "start", - ["meta.tag","items"], - ["keyword",":"] -],[ - "start", - ["list.markup"," - "], - ["meta.tag","part_no"], - ["keyword",":"], - ["text"," "], - ["string","'A4786'"] -],[ - "start", - ["meta.tag"," descrip"], - ["keyword",":"], - ["text"," Water Bucket "], - ["paren.lparen","("], - ["text","Filled)"] -],[ - "start", - ["meta.tag"," price"], - ["keyword",":"], - ["text"," "], - ["constant.numeric","1.47"] -],[ - "start", - ["meta.tag"," quantity"], - ["keyword",":"], - ["text"," "], - ["constant.numeric","4"] -],[ - "start" -],[ - "start", - ["list.markup"," - "], - ["meta.tag","part_no"], - ["keyword",":"], - ["text"," "], - ["string","'E1628'"] -],[ - "start", - ["meta.tag"," descrip"], - ["keyword",":"], - ["text"," High Heeled "], - ["string","\"Ruby\""], - ["text"," Slippers"] -],[ - "start", - ["meta.tag"," size"], - ["keyword",":"], - ["text"," "], - ["constant.numeric","8"] -],[ - "start", - ["meta.tag"," price"], - ["keyword",":"], - ["text"," "], - ["constant.numeric","100.27"] -],[ - "start", - ["meta.tag"," quantity"], - ["keyword",":"], - ["text"," "], - ["constant.numeric","1"] -],[ - "start" -],[ - "start", - ["meta.tag","bill-to"], - ["keyword",":"], - ["text"," "], - ["constant.language","&id001"] -],[ - ["mlString",4], - ["meta.tag"," street"], - ["keyword",":"], - ["text"," "], - ["string","|"] -],[ - ["mlString",4], - ["indent"," "], - ["string","123 Tornado Alley"] -],[ - ["mlString",4], - ["indent"," "], - ["string","Suite 16"] -],[ - "start", - ["indent"," "], - ["meta.tag","city"], - ["keyword",":"], - ["text"," East Centerville"] -],[ - "start", - ["meta.tag"," state"], - ["keyword",":"], - ["text"," KS"] -],[ - "start" -],[ - "start", - ["meta.tag","ship-to"], - ["keyword",":"], - ["text"," "], - ["constant.language","*id001"] -],[ - "start" -],[ - ["mlString",0], - ["meta.tag","specialDelivery"], - ["keyword",":"], - ["text"," "], - ["string",">"] -],[ - ["mlString",0], - ["indent"," "], - ["string","Follow the Yellow Brick"] -],[ - ["mlString",0], - ["indent"," "], - ["string","Road to the Emerald City."] -],[ - ["mlString",0], - ["indent"," "], - ["string","Pay no attention to the"] -],[ - ["mlString",0], - ["indent"," "], - ["string","man behind the curtain."] -],[ - ["mlString",0] -]] \ No newline at end of file diff --git a/lib/ace/mode/abap.js b/lib/ace/mode/abap.js deleted file mode 100644 index 33d85e8fc9a..00000000000 --- a/lib/ace/mode/abap.js +++ /dev/null @@ -1,61 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var Rules = require("./abap_highlight_rules").AbapHighlightRules; -var FoldMode = require("./folding/coffee").FoldMode; -var Range = require("../range").Range; -var TextMode = require("./text").Mode; -var oop = require("../lib/oop"); - -function Mode() { - this.HighlightRules = Rules; - this.foldingRules = new FoldMode(); -} - -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = '"'; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - return indent; - }; - - this.$id = "ace/mode/abap"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); diff --git a/lib/ace/mode/abc.js b/lib/ace/mode/abc.js deleted file mode 100644 index 344c950629a..00000000000 --- a/lib/ace/mode/abc.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js - */ - -define(function (require, exports, module) { - "use strict"; - - var oop = require("../lib/oop"); - var TextMode = require("./text").Mode; - var ABCHighlightRules = require("./abc_highlight_rules").ABCHighlightRules; - var FoldMode = require("./folding/cstyle").FoldMode; - - var Mode = function () { - this.HighlightRules = ABCHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; - }; - oop.inherits(Mode, TextMode); - - (function () { - // this.lineCommentStart = ""%.*""; - // this.blockComment = {start: ""/*"", end: ""*/""}; - // Extra logic goes here. - this.$id = "ace/mode/abc"; - }).call(Mode.prototype); - - exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/actionscript.js b/lib/ace/mode/actionscript.js deleted file mode 100644 index 70eaaba684b..00000000000 --- a/lib/ace/mode/actionscript.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var ActionScriptHighlightRules = require("./actionscript_highlight_rules").ActionScriptHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = ActionScriptHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - this.$id = "ace/mode/actionscript"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/ada.js b/lib/ace/mode/ada.js deleted file mode 100644 index fabf04dc050..00000000000 --- a/lib/ace/mode/ada.js +++ /dev/null @@ -1,54 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var AdaHighlightRules = require("./ada_highlight_rules").AdaHighlightRules; - -var Mode = function() { - this.HighlightRules = AdaHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "--"; - - this.$id = "ace/mode/ada"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); - diff --git a/lib/ace/mode/ada_highlight_rules.js b/lib/ace/mode/ada_highlight_rules.js deleted file mode 100644 index b345966c4f6..00000000000 --- a/lib/ace/mode/ada_highlight_rules.js +++ /dev/null @@ -1,93 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var AdaHighlightRules = function() { -var keywords = "abort|else|new|return|abs|elsif|not|reverse|abstract|end|null|accept|entry|select|" + -"access|exception|of|separate|aliased|exit|or|some|all|others|subtype|and|for|out|synchronized|" + -"array|function|overriding|at|tagged|generic|package|task|begin|goto|pragma|terminate|" + -"body|private|then|if|procedure|type|case|in|protected|constant|interface|until|" + -"|is|raise|use|declare|range|delay|limited|record|when|delta|loop|rem|while|digits|renames|with|do|mod|requeue|xor"; - - var builtinConstants = ( - "true|false|null" - ); - - var builtinFunctions = ( - "count|min|max|avg|sum|rank|now|coalesce|main" - ); - - var keywordMapper = this.createKeywordMapper({ - "support.function": builtinFunctions, - "keyword": keywords, - "constant.language": builtinConstants - }, "identifier", true); - - this.$rules = { - "start" : [ { - token : "comment", - regex : "--.*$" - }, { - token : "string", // " string - regex : '".*?"' - }, { - token : "string", // ' string - regex : "'.*?'" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "keyword.operator", - regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|=" - }, { - token : "paren.lparen", - regex : "[\\(]" - }, { - token : "paren.rparen", - regex : "[\\)]" - }, { - token : "text", - regex : "\\s+" - } ] - }; -}; - -oop.inherits(AdaHighlightRules, TextHighlightRules); - -exports.AdaHighlightRules = AdaHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/apache_conf.js b/lib/ace/mode/apache_conf.js deleted file mode 100644 index dec48d156b4..00000000000 --- a/lib/ace/mode/apache_conf.js +++ /dev/null @@ -1,62 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var ApacheConfHighlightRules = require("./apache_conf_highlight_rules").ApacheConfHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = ApacheConfHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "#"; - this.$id = "ace/mode/apache_conf"; - // Extra logic goes here. -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/applescript.js b/lib/ace/mode/applescript.js deleted file mode 100644 index 90a79fba8de..00000000000 --- a/lib/ace/mode/applescript.js +++ /dev/null @@ -1,54 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var AppleScriptHighlightRules = require("./applescript_highlight_rules").AppleScriptHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = AppleScriptHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "--"; - this.blockComment = {start: "(*", end: "*)"}; - this.$id = "ace/mode/applescript"; - // Extra logic goes here. -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/applescript_highlight_rules.js b/lib/ace/mode/applescript_highlight_rules.js deleted file mode 100644 index 6bcad0f2869..00000000000 --- a/lib/ace/mode/applescript_highlight_rules.js +++ /dev/null @@ -1,139 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var AppleScriptHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - var keywords = ( - "about|above|after|against|and|around|as|at|back|before|beginning|" + - "behind|below|beneath|beside|between|but|by|considering|" + - "contain|contains|continue|copy|div|does|eighth|else|end|equal|" + - "equals|error|every|exit|fifth|first|for|fourth|from|front|" + - "get|given|global|if|ignoring|in|into|is|it|its|last|local|me|" + - "middle|mod|my|ninth|not|of|on|onto|or|over|prop|property|put|ref|" + - "reference|repeat|returning|script|second|set|seventh|since|" + - "sixth|some|tell|tenth|that|the|then|third|through|thru|" + - "timeout|times|to|transaction|try|until|where|while|whose|with|without" - ); - - var builtinConstants = ( - "AppleScript|false|linefeed|return|pi|quote|result|space|tab|true" - ); - - var builtinFunctions = ( - "activate|beep|count|delay|launch|log|offset|read|round|run|say|" + - "summarize|write" - ); - - var builtinTypes = ( - "alias|application|boolean|class|constant|date|file|integer|list|" + - "number|real|record|string|text|character|characters|contents|day|" + - "frontmost|id|item|length|month|name|paragraph|paragraphs|rest|" + - "reverse|running|time|version|weekday|word|words|year" - ); - - var keywordMapper = this.createKeywordMapper({ - "support.function": builtinFunctions, - "constant.language": builtinConstants, - "support.type": builtinTypes, - "keyword": keywords - }, "identifier"); - - this.$rules = { - "start": [ - { - token: "comment", - regex: "--.*$" - }, - { - token : "comment", // multi line comment - regex : "\\(\\*", - next : "comment" - }, - { - token: "string", // " string - regex: '".*?"' - }, - { - token: "support.type", - regex: '\\b(POSIX file|POSIX path|(date|time) string|quoted form)\\b' - }, - { - token: "support.function", - regex: '\\b(clipboard info|the clipboard|info for|list (disks|folder)|' + - 'mount volume|path to|(close|open for) access|(get|set) eof|' + - 'current date|do shell script|get volume settings|random number|' + - 'set volume|system attribute|system info|time to GMT|' + - '(load|run|store) script|scripting components|' + - 'ASCII (character|number)|localized string|' + - 'choose (application|color|file|file name|' + - 'folder|from list|remote application|URL)|' + - 'display (alert|dialog))\\b|^\\s*return\\b' - }, - { - token: "constant.language", - regex: '\\b(text item delimiters|current application|missing value)\\b' - }, - { - token: "keyword", - regex: '\\b(apart from|aside from|instead of|out of|greater than|' + - "isn't|(doesn't|does not) (equal|come before|come after|contain)|" + - '(greater|less) than( or equal)?|(starts?|ends|begins?) with|' + - 'contained by|comes (before|after)|a (ref|reference))\\b' - }, - { - token: keywordMapper, - regex: "[a-zA-Z][a-zA-Z0-9_]*\\b" - } - ], - "comment": [ - { - token: "comment", // closing comment - regex: "\\*\\)", - next: "start" - }, { - defaultToken: "comment" - } - ] - }; - - this.normalizeRules(); -}; - -oop.inherits(AppleScriptHighlightRules, TextHighlightRules); - -exports.AppleScriptHighlightRules = AppleScriptHighlightRules; -}); diff --git a/lib/ace/mode/asciidoc.js b/lib/ace/mode/asciidoc.js deleted file mode 100644 index 894d9763ec2..00000000000 --- a/lib/ace/mode/asciidoc.js +++ /dev/null @@ -1,64 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var AsciidocHighlightRules = require("./asciidoc_highlight_rules").AsciidocHighlightRules; -var AsciidocFoldMode = require("./folding/asciidoc").FoldMode; - -var Mode = function() { - this.HighlightRules = AsciidocHighlightRules; - - this.foldingRules = new AsciidocFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - this.type = "text"; - this.getNextLineIndent = function(state, line, tab) { - if (state == "listblock") { - var match = /^((?:.+)?)([-+*][ ]+)/.exec(line); - if (match) { - return new Array(match[1].length + 1).join(" ") + match[2]; - } else { - return ""; - } - } else { - return this.$getIndent(line); - } - }; - this.$id = "ace/mode/asciidoc"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/asl.js b/lib/ace/mode/asl.js deleted file mode 100755 index 04ddae57921..00000000000 --- a/lib/ace/mode/asl.js +++ /dev/null @@ -1,51 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function (require, exports, module) { - "use strict"; - - var oop = require("../lib/oop"); - var TextMode = require("./text").Mode; - var ASLHighlightRules = require("./asl_highlight_rules").ASLHighlightRules; - var FoldMode = require("./folding/cstyle").FoldMode; - - var Mode = function () { - this.HighlightRules = ASLHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; - }; - oop.inherits(Mode, TextMode); - - (function () { - this.$id = "ace/mode/asl"; - }).call(Mode.prototype); - - exports.Mode = Mode; -}); diff --git a/lib/ace/mode/assembly_x86.js b/lib/ace/mode/assembly_x86.js deleted file mode 100644 index 525f1778803..00000000000 --- a/lib/ace/mode/assembly_x86.js +++ /dev/null @@ -1,57 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var AssemblyX86HighlightRules = require("./assembly_x86_highlight_rules").AssemblyX86HighlightRules; -var FoldMode = require("./folding/coffee").FoldMode; - -var Mode = function() { - this.HighlightRules = AssemblyX86HighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = [";", "#"]; - this.$id = "ace/mode/assembly_x86"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/autohotkey.js b/lib/ace/mode/autohotkey.js deleted file mode 100644 index 3ac647c8096..00000000000 --- a/lib/ace/mode/autohotkey.js +++ /dev/null @@ -1,57 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var AutoHotKeyHighlightRules = require("./autohotkey_highlight_rules").AutoHotKeyHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = AutoHotKeyHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = ";"; - this.blockComment = {start: "/*", end: "*/"}; - this.$id = "ace/mode/autohotkey"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/batchfile.js b/lib/ace/mode/batchfile.js deleted file mode 100644 index 052a2384b1c..00000000000 --- a/lib/ace/mode/batchfile.js +++ /dev/null @@ -1,62 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var BatchFileHighlightRules = require("./batchfile_highlight_rules").BatchFileHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = BatchFileHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "::"; - this.blockComment = ""; - this.$id = "ace/mode/batchfile"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/batchfile_highlight_rules.js b/lib/ace/mode/batchfile_highlight_rules.js deleted file mode 100644 index af4b0ec527e..00000000000 --- a/lib/ace/mode/batchfile_highlight_rules.js +++ /dev/null @@ -1,97 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* This file was autogenerated from C:\Users\LED\AppData\Roaming\Sublime Text 2\Packages\Batch File\Batch File.tmLanguage (uuid: ) */ -/**************************************************************************************** - * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * - * fileTypes * - ****************************************************************************************/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var BatchFileHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { start: - [ { token: 'keyword.command.dosbatch', - 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', - caseInsensitive: true }, - { token: 'keyword.control.statement.dosbatch', - regex: '\\b(?:goto|call|exit)\\b', - caseInsensitive: true }, - { token: 'keyword.control.conditional.if.dosbatch', - regex: '\\bif\\s+not\\s+(?:exist|defined|errorlevel|cmdextversion)\\b', - caseInsensitive: true }, - { token: 'keyword.control.conditional.dosbatch', - regex: '\\b(?:if|else)\\b', - caseInsensitive: true }, - { token: 'keyword.control.repeat.dosbatch', - regex: '\\bfor\\b', - caseInsensitive: true }, - { token: 'keyword.operator.dosbatch', - regex: '\\b(?:EQU|NEQ|LSS|LEQ|GTR|GEQ)\\b' }, - { token: ['doc.comment', 'comment'], - regex: '(?:^|\\b)(rem)($|\\s.*$)', - caseInsensitive: true }, - { token: 'comment.line.colons.dosbatch', - regex: '::.*$' }, - { include: 'variable' }, - { token: 'punctuation.definition.string.begin.shell', - regex: '"', - push: [ - { token: 'punctuation.definition.string.end.shell', regex: '"', next: 'pop' }, - { include: 'variable' }, - { defaultToken: 'string.quoted.double.dosbatch' } ] }, - { token: 'keyword.operator.pipe.dosbatch', regex: '[|]' }, - { token: 'keyword.operator.redirect.shell', - regex: '&>|\\d*>&\\d*|\\d*(?:>>|>|<)|\\d*<&|\\d*<>' } ], - variable: [ - { token: 'constant.numeric', regex: '%%\\w+|%[*\\d]|%\\w+%'}, - { token: 'constant.numeric', regex: '%~\\d+'}, - { token: ['markup.list', 'constant.other', 'markup.list'], - regex: '(%)(\\w+)(%?)' }]}; - - this.normalizeRules(); -}; - -BatchFileHighlightRules.metaData = { name: 'Batch File', - scopeName: 'source.dosbatch', - fileTypes: [ 'bat' ] }; - - -oop.inherits(BatchFileHighlightRules, TextHighlightRules); - -exports.BatchFileHighlightRules = BatchFileHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/behaviour.js b/lib/ace/mode/behaviour.js deleted file mode 100644 index abb5a995be9..00000000000 --- a/lib/ace/mode/behaviour.js +++ /dev/null @@ -1,90 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var Behaviour = function() { - this.$behaviours = {}; -}; - -(function () { - - this.add = function (name, action, callback) { - switch (undefined) { - case this.$behaviours: - this.$behaviours = {}; - case this.$behaviours[name]: - this.$behaviours[name] = {}; - } - this.$behaviours[name][action] = callback; - }; - - this.addBehaviours = function (behaviours) { - for (var key in behaviours) { - for (var action in behaviours[key]) { - this.add(key, action, behaviours[key][action]); - } - } - }; - - this.remove = function (name) { - if (this.$behaviours && this.$behaviours[name]) { - delete this.$behaviours[name]; - } - }; - - this.inherit = function (mode, filter) { - if (typeof mode === "function") { - var behaviours = new mode().getBehaviours(filter); - } else { - var behaviours = mode.getBehaviours(filter); - } - this.addBehaviours(behaviours); - }; - - this.getBehaviours = function (filter) { - if (!filter) { - return this.$behaviours; - } else { - var ret = {}; - for (var i = 0; i < filter.length; i++) { - if (this.$behaviours[filter[i]]) { - ret[filter[i]] = this.$behaviours[filter[i]]; - } - } - return ret; - } - }; - -}).call(Behaviour.prototype); - -exports.Behaviour = Behaviour; -}); diff --git a/lib/ace/mode/behaviour/behaviour_test.js b/lib/ace/mode/behaviour/behaviour_test.js deleted file mode 100644 index 500f3971d41..00000000000 --- a/lib/ace/mode/behaviour/behaviour_test.js +++ /dev/null @@ -1,392 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") { - require("amd-loader"); - require("../../test/mockdom"); -} - -define(function(require, exports, module) { -"use strict"; - -require("../../multi_select"); -var assert = require("../../test/assertions"); -var Range = require("../../range").Range; -var Editor = require("../../editor").Editor; -var UndoManager = require("../../undomanager").UndoManager; -var EditSession = require("../../edit_session").EditSession; -var MockRenderer = require("../../test/mockrenderer").MockRenderer; -var JavaScriptMode = require("../javascript").Mode; -var RustMode = require("../rust").Mode; -var XMLMode = require("../xml").Mode; -var HTMLMode = require("../html").Mode; -var CSSMode = require("../css").Mode; -var editor; -var exec = function(name, times, args) { - do { - editor.commands.exec(name, editor, args); - } while(times --> 1); -}; -var testRanges = function(str) { - assert.equal(editor.selection.getAllRanges() + "", str + ""); -}; - -module.exports = { - "test: cstyle": function() { - function testValue(line) { - assert.equal(editor.getValue(), Array(4).join(line + "\n")); - } - function testSelection(line, col, inc) { - editor.selection.rangeList.ranges.forEach(function(r) { - assert.range(r, line, col, line, col); - line += (inc || 1); - }); - } - var doc = new EditSession([ - "", - "", - "", - "" - ], new JavaScriptMode()); - editor = new Editor(new MockRenderer(), doc); - editor.setOption("behavioursEnabled", true); - - editor.navigateFileStart(); - exec("addCursorBelow", 2); - - exec("insertstring", 1, "if "); - - // pairing ( - exec("insertstring", 1, "("); - testValue("if ()"); - testSelection(0, 4); - exec("insertstring", 1, ")"); - testValue("if ()"); - testSelection(0, 5); - - // pairing [ - exec("gotoleft", 1); - exec("insertstring", 1, "["); - testValue("if ([])"); - testSelection(0, 5); - - exec("insertstring", 1, "]"); - testValue("if ([])"); - testSelection(0, 6); - - // test deletion - exec("gotoleft", 1); - exec("backspace", 1); - testValue("if ()"); - testSelection(0, 4); - - exec("gotolineend", 1); - exec("insertstring", 1, "{"); - testValue("if (){}"); - testSelection(0, 6); - - exec("insertstring", 1, "}"); - testValue("if (){}"); - testSelection(0, 7); - - exec("gotolinestart", 1); - exec("insertstring", 1, "("); - testValue("(if (){}"); - exec("backspace", 1); - - editor.setValue(""); - exec("insertstring", 1, "{"); - assert.equal(editor.getValue(), "{"); - exec("insertstring", 1, "\n"); - assert.equal(editor.getValue(), "{\n \n}"); - - editor.setValue(""); - exec("insertstring", 1, "("); - exec("insertstring", 1, '"'); - exec("insertstring", 1, '"'); - assert.equal(editor.getValue(), '("")'); - exec("backspace", 1); - exec("insertstring", 1, '"'); - assert.equal(editor.getValue(), '("")'); - - editor.setValue("('foo')", 1); - exec("gotoleft", 1); - exec("selectleft", 1); - exec("selectMoreBefore", 1); - exec("insertstring", 1, "'"); - assert.equal(editor.getValue(), "('foo')"); - exec("selectleft", 1); - exec("insertstring", 1, '"'); - assert.equal(editor.getValue(), '("foo")'); - exec("selectleft", 1); - exec("insertstring", 1, '"'); - assert.equal(editor.getValue(), '("foo")'); - - editor.setValue("", 1); - exec("selectleft", 1); - exec("insertstring", 1, '"'); - assert.equal(editor.getValue(), '""'); - exec("insertstring", 1, '\\'); - exec("insertstring", 1, 'n'); - exec("insertstring", 1, '"'); - assert.equal(editor.getValue(), '"\\n"'); - - }, - "test: xml": function() { - editor = new Editor(new MockRenderer()); - editor.session.setUndoManager(new UndoManager()); - editor.setValue(["", - " " - ].join("\n")); - editor.session.setMode(new XMLMode); - exec("golinedown", 1); - exec("gotolineend", 1); - exec("insertstring", 1, '\n'); - assert.equal(editor.session.getLine(2), " "); - exec("gotolineup", 1); - exec("gotolineend", 1); - exec("insertstring", 1, '\n'); - assert.equal(editor.session.getLine(2), " "); - editor.session.setValue(["'); - assert.equal(editor.session.getLine(1), " "); - - editor.setValue(["" - ].join("\n")); - editor.selection.moveTo(0, 100); - exec("insertstring", 1, '>'); - editor.selection.moveTo(1, 100); - exec("insertstring", 1, '>'); - editor.selection.moveTo(2, 1); - exec("insertstring", 1, '>'); - editor.selection.moveTo(3, 1); - exec("insertstring", 1, '>'); - assert.equal(editor.getValue(), [ - "", - " >" - ].join("\n")); - - editor.setValue(""); - "
      ".split("").forEach(function(ch) { - exec("insertstring", 1, ch); - }); - assert.equal(editor.getValue(), "
      "); - exec("insertstring", 1, ">"); - assert.equal(editor.getValue(), "
      >
      "); - - editor.setValue("
      ", 1); - exec("gotoleft", 7); - exec("insertstring", 1, '"'); - assert.equal(editor.getValue(), "
      "); - exec("insertstring", 1, '"'); - exec("gotoright", 1); - exec("insertstring", 1, "\n"); - assert.equal(editor.getValue(), "
      \n \n
      "); - - exec("undo", 1); - assert.equal(editor.getValue(), "
      "); - exec("gotoleft", 1); - exec("backspace", 1); - assert.equal(editor.getValue(), "
      "); - exec("undo", 1); - exec("gotoleft", 1); - exec("backspace", 1); - assert.equal(editor.getValue(), "
      "); - exec("backspace", 1); - assert.equal(editor.getValue(), "
      "); - - editor.setValue("
      ", 1); - editor.selection.moveTo(0, 9); - exec("insertstring", 1, "\n"); - assert.equal(editor.getValue(), "
      \n
      "); - - editor.setValue("
      ", 1); - exec("insertstring", 1, "\n"); - assert.equal(editor.getValue(), "
      \n "); - - editor.setValue("

      ", 1); - editor.selection.moveTo(0, 8); - exec("insertstring", 1, "\n"); - assert.equal(editor.getValue(), "
      \n
      "); - - editor.setValue("
      x"); - - editor.setValue(""); - "
      ".split("").forEach(function(ch) { - exec("insertstring", 1, ch); - }); - assert.equal(editor.getValue(), "
      "); - }, - "test: quotes": function() { - editor = new Editor(new MockRenderer()); - editor.session.setMode(new RustMode); - editor.setValue(""); - exec("insertstring", 1, '"'); - exec("insertstring", 1, 'a'); - assert.equal(editor.getValue(), '"a"'); - exec("backspace", 2); - exec("insertstring", 1, "'"); - assert.equal(editor.getValue(), "'"); - - editor.session.setMode(new JavaScriptMode); - editor.setValue(""); - exec("insertstring", 1, '"'); - exec("insertstring", 1, 'a'); - assert.equal(editor.getValue(), '"a"'); - exec("backspace", 2); - exec("insertstring", 1, "'"); - assert.equal(editor.getValue(), "''"); - exec("backspace", 1); - exec("insertstring", 1, '`'); - exec("insertstring", 1, 'b'); - assert.equal(editor.getValue(), "`b`"); - }, - "test: css": function() { - editor.session.setMode(new CSSMode()); - editor.setWrapBehavioursEnabled(true); - editor.setValue("a {padding", 1); - exec("insertstring", 1, ":"); - assert.equal(editor.getValue(), "a {padding:;"); - - editor.setValue("a {padding:", 1); - exec("gotoleft", 1); - exec("insertstring", 1, ":"); - assert.equal(editor.getValue(), "a {padding:"); - - editor.setValue("a {padding ", 1); - exec("insertstring", 1, ":"); - assert.equal(editor.getValue(), "a {padding :;"); - - editor.setValue("a", 1); - exec("insertstring", 1, ":"); - assert.equal(editor.getValue(), "a:"); - - editor.setValue("a {padding", 1); - exec("insertstring", 1, ":"); - exec("backspace", 1); - assert.equal(editor.getValue(), "a {padding"); - exec("backspace", 2); - exec("insertstring", 1, ":;"); - exec("gotoleft", 1); - exec("backspace", 1); - assert.equal(editor.getValue(), "a {paddi;"); - - editor.setValue("a {padding :", 1); - exec("backspace", 1); - assert.equal(editor.getValue(), "a {padding "); - - - editor.setValue("a {padding:", 1); - exec("insertstring", 1, ";"); - assert.equal(editor.getValue(), "a {padding:;"); - - editor.setValue(";", 1); - exec("gotoleft", 1); - exec("insertstring", 1, "a {padding"); - exec("insertstring", 1, ":"); - assert.equal(editor.getValue(), "a {padding:;"); - - editor.setValue(";", 1); - exec("selectleft", 1); - exec("insertstring", 1, ";"); - assert.equal(editor.getValue(), ";"); - - editor.setValue("a {padding:;", 1); - exec("gotoleft", 1); - exec("insertstring", 1, ";"); - assert.equal(editor.getValue(), "a {padding:;"); - - editor.setValue("a {padding:10px", 1); - exec("insertstring", 1, "!"); - assert.equal(editor.getValue(), "a {padding:10px!important"); - exec("removewordleft", 2); - exec("insertstring", 1, "}"); - exec("gotoleft", 1); - exec("insertstring", 1, "!"); - assert.equal(editor.getValue(), "a {padding:10px!important}"); - exec("removewordleft", 2); - exec("insertstring", 1, ";"); - exec("gotoleft", 1); - exec("insertstring", 1, "!"); - assert.equal(editor.getValue(), "a {padding:10px!important;}"); - editor.selection.moveTo(0, 3); - exec("insertstring", 1, "!"); - assert.equal(editor.getValue(), "a {!padding:10px!important;}"); - } - -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/mode/behaviour/css.js b/lib/ace/mode/behaviour/css.js deleted file mode 100644 index abde6ead07f..00000000000 --- a/lib/ace/mode/behaviour/css.js +++ /dev/null @@ -1,122 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var Behaviour = require("../behaviour").Behaviour; -var CstyleBehaviour = require("./cstyle").CstyleBehaviour; -var TokenIterator = require("../../token_iterator").TokenIterator; - -var CssBehaviour = function () { - - this.inherit(CstyleBehaviour); - - this.add("colon", "insertion", function (state, action, editor, session, text) { - if (text === ':' && editor.selection.isEmpty()) { - var cursor = editor.getCursorPosition(); - var iterator = new TokenIterator(session, cursor.row, cursor.column); - var token = iterator.getCurrentToken(); - if (token && token.value.match(/\s+/)) { - token = iterator.stepBackward(); - } - if (token && token.type === 'support.type') { - var line = session.doc.getLine(cursor.row); - var rightChar = line.substring(cursor.column, cursor.column + 1); - if (rightChar === ':') { - return { - text: '', - selection: [1, 1] - }; - } - if (/^(\s+[^;]|\s*$)/.test(line.substring(cursor.column))) { - return { - text: ':;', - selection: [1, 1] - }; - } - } - } - }); - - this.add("colon", "deletion", function (state, action, editor, session, range) { - var selected = session.doc.getTextRange(range); - if (!range.isMultiLine() && selected === ':') { - var cursor = editor.getCursorPosition(); - var iterator = new TokenIterator(session, cursor.row, cursor.column); - var token = iterator.getCurrentToken(); - if (token && token.value.match(/\s+/)) { - token = iterator.stepBackward(); - } - if (token && token.type === 'support.type') { - var line = session.doc.getLine(range.start.row); - var rightChar = line.substring(range.end.column, range.end.column + 1); - if (rightChar === ';') { - range.end.column ++; - return range; - } - } - } - }); - - this.add("semicolon", "insertion", function (state, action, editor, session, text) { - if (text === ';' && editor.selection.isEmpty()) { - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - var rightChar = line.substring(cursor.column, cursor.column + 1); - if (rightChar === ';') { - return { - text: '', - selection: [1, 1] - }; - } - } - }); - - this.add("!important", "insertion", function (state, action, editor, session, text) { - if (text === '!' && editor.selection.isEmpty()) { - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - - if (/^\s*(;|}|$)/.test(line.substring(cursor.column))) { - return { - text: '!important', - selection: [10, 10] - }; - } - } - }); - -}; -oop.inherits(CssBehaviour, CstyleBehaviour); - -exports.CssBehaviour = CssBehaviour; -}); diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js deleted file mode 100644 index 317c52c656f..00000000000 --- a/lib/ace/mode/behaviour/cstyle.js +++ /dev/null @@ -1,400 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var Behaviour = require("../behaviour").Behaviour; -var TokenIterator = require("../../token_iterator").TokenIterator; -var lang = require("../../lib/lang"); - -var SAFE_INSERT_IN_TOKENS = - ["text", "paren.rparen", "punctuation.operator"]; -var SAFE_INSERT_BEFORE_TOKENS = - ["text", "paren.rparen", "punctuation.operator", "comment"]; - -var context; -var contextCache = {}; -var defaultQuotes = {'"' : '"', "'" : "'"}; - -var initContext = function(editor) { - var id = -1; - if (editor.multiSelect) { - id = editor.selection.index; - if (contextCache.rangeCount != editor.multiSelect.rangeCount) - contextCache = {rangeCount: editor.multiSelect.rangeCount}; - } - if (contextCache[id]) - return context = contextCache[id]; - context = contextCache[id] = { - autoInsertedBrackets: 0, - autoInsertedRow: -1, - autoInsertedLineEnd: "", - maybeInsertedBrackets: 0, - maybeInsertedRow: -1, - maybeInsertedLineStart: "", - maybeInsertedLineEnd: "" - }; -}; - -var getWrapped = function(selection, selected, opening, closing) { - var rowDiff = selection.end.row - selection.start.row; - return { - text: opening + selected + closing, - selection: [ - 0, - selection.start.column + 1, - rowDiff, - selection.end.column + (rowDiff ? 0 : 1) - ] - }; -}; - -var CstyleBehaviour = function(options) { - this.add("braces", "insertion", function(state, action, editor, session, text) { - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - if (text == '{') { - initContext(editor); - var selection = editor.getSelectionRange(); - var selected = session.doc.getTextRange(selection); - if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) { - return getWrapped(selection, selected, '{', '}'); - } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { - if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode || options && options.braces) { - CstyleBehaviour.recordAutoInsert(editor, session, "}"); - return { - text: '{}', - selection: [1, 1] - }; - } else { - CstyleBehaviour.recordMaybeInsert(editor, session, "{"); - return { - text: '{', - selection: [1, 1] - }; - } - } - } else if (text == '}') { - initContext(editor); - var rightChar = line.substring(cursor.column, cursor.column + 1); - if (rightChar == '}') { - var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row}); - if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { - CstyleBehaviour.popAutoInsertedClosing(); - return { - text: '', - selection: [1, 1] - }; - } - } - } else if (text == "\n" || text == "\r\n") { - initContext(editor); - var closing = ""; - if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) { - closing = lang.stringRepeat("}", context.maybeInsertedBrackets); - CstyleBehaviour.clearMaybeInsertedClosing(); - } - var rightChar = line.substring(cursor.column, cursor.column + 1); - if (rightChar === '}') { - var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}'); - if (!openBracePos) - return null; - var next_indent = this.$getIndent(session.getLine(openBracePos.row)); - } else if (closing) { - var next_indent = this.$getIndent(line); - } else { - CstyleBehaviour.clearMaybeInsertedClosing(); - return; - } - var indent = next_indent + session.getTabString(); - - return { - text: '\n' + indent + '\n' + next_indent + closing, - selection: [1, indent.length, 1, indent.length] - }; - } else { - CstyleBehaviour.clearMaybeInsertedClosing(); - } - }); - - this.add("braces", "deletion", function(state, action, editor, session, range) { - var selected = session.doc.getTextRange(range); - if (!range.isMultiLine() && selected == '{') { - initContext(editor); - var line = session.doc.getLine(range.start.row); - var rightChar = line.substring(range.end.column, range.end.column + 1); - if (rightChar == '}') { - range.end.column++; - return range; - } else { - context.maybeInsertedBrackets--; - } - } - }); - - this.add("parens", "insertion", function(state, action, editor, session, text) { - if (text == '(') { - initContext(editor); - var selection = editor.getSelectionRange(); - var selected = session.doc.getTextRange(selection); - if (selected !== "" && editor.getWrapBehavioursEnabled()) { - return getWrapped(selection, selected, '(', ')'); - } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { - CstyleBehaviour.recordAutoInsert(editor, session, ")"); - return { - text: '()', - selection: [1, 1] - }; - } - } else if (text == ')') { - initContext(editor); - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - var rightChar = line.substring(cursor.column, cursor.column + 1); - if (rightChar == ')') { - var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row}); - if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { - CstyleBehaviour.popAutoInsertedClosing(); - return { - text: '', - selection: [1, 1] - }; - } - } - } - }); - - this.add("parens", "deletion", function(state, action, editor, session, range) { - var selected = session.doc.getTextRange(range); - if (!range.isMultiLine() && selected == '(') { - initContext(editor); - var line = session.doc.getLine(range.start.row); - var rightChar = line.substring(range.start.column + 1, range.start.column + 2); - if (rightChar == ')') { - range.end.column++; - return range; - } - } - }); - - this.add("brackets", "insertion", function(state, action, editor, session, text) { - if (text == '[') { - initContext(editor); - var selection = editor.getSelectionRange(); - var selected = session.doc.getTextRange(selection); - if (selected !== "" && editor.getWrapBehavioursEnabled()) { - return getWrapped(selection, selected, '[', ']'); - } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { - CstyleBehaviour.recordAutoInsert(editor, session, "]"); - return { - text: '[]', - selection: [1, 1] - }; - } - } else if (text == ']') { - initContext(editor); - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - var rightChar = line.substring(cursor.column, cursor.column + 1); - if (rightChar == ']') { - var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row}); - if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { - CstyleBehaviour.popAutoInsertedClosing(); - return { - text: '', - selection: [1, 1] - }; - } - } - } - }); - - this.add("brackets", "deletion", function(state, action, editor, session, range) { - var selected = session.doc.getTextRange(range); - if (!range.isMultiLine() && selected == '[') { - initContext(editor); - var line = session.doc.getLine(range.start.row); - var rightChar = line.substring(range.start.column + 1, range.start.column + 2); - if (rightChar == ']') { - range.end.column++; - return range; - } - } - }); - - this.add("string_dquotes", "insertion", function(state, action, editor, session, text) { - var quotes = session.$mode.$quotes || defaultQuotes; - if (text.length == 1 && quotes[text]) { - if (this.lineCommentStart && this.lineCommentStart.indexOf(text) != -1) - return; - initContext(editor); - var quote = text; - var selection = editor.getSelectionRange(); - var selected = session.doc.getTextRange(selection); - if (selected !== "" && (selected.length != 1 || !quotes[selected]) && editor.getWrapBehavioursEnabled()) { - return getWrapped(selection, selected, quote, quote); - } else if (!selected) { - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - var leftChar = line.substring(cursor.column-1, cursor.column); - var rightChar = line.substring(cursor.column, cursor.column + 1); - - var token = session.getTokenAt(cursor.row, cursor.column); - var rightToken = session.getTokenAt(cursor.row, cursor.column + 1); - // We're escaped. - if (leftChar == "\\" && token && /escape/.test(token.type)) - return null; - - var stringBefore = token && /string|escape/.test(token.type); - var stringAfter = !rightToken || /string|escape/.test(rightToken.type); - - var pair; - if (rightChar == quote) { - pair = stringBefore !== stringAfter; - if (pair && /string\.end/.test(rightToken.type)) - pair = false; - } else { - if (stringBefore && !stringAfter) - return null; // wrap string with different quote - if (stringBefore && stringAfter) - return null; // do not pair quotes inside strings - var wordRe = session.$mode.tokenRe; - wordRe.lastIndex = 0; - var isWordBefore = wordRe.test(leftChar); - wordRe.lastIndex = 0; - var isWordAfter = wordRe.test(leftChar); - if (isWordBefore || isWordAfter) - return null; // before or after alphanumeric - if (rightChar && !/[\s;,.})\]\\]/.test(rightChar)) - return null; // there is rightChar and it isn't closing - pair = true; - } - return { - text: pair ? quote + quote : "", - selection: [1,1] - }; - } - } - }); - - this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { - var selected = session.doc.getTextRange(range); - if (!range.isMultiLine() && (selected == '"' || selected == "'")) { - initContext(editor); - var line = session.doc.getLine(range.start.row); - var rightChar = line.substring(range.start.column + 1, range.start.column + 2); - if (rightChar == selected) { - range.end.column++; - return range; - } - } - }); - -}; - - -CstyleBehaviour.isSaneInsertion = function(editor, session) { - var cursor = editor.getCursorPosition(); - var iterator = new TokenIterator(session, cursor.row, cursor.column); - - // Don't insert in the middle of a keyword/identifier/lexical - if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) { - // Look ahead in case we're at the end of a token - var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1); - if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) - return false; - } - - // Only insert in front of whitespace/comments - iterator.stepForward(); - return iterator.getCurrentTokenRow() !== cursor.row || - this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS); -}; - -CstyleBehaviour.$matchTokenType = function(token, types) { - return types.indexOf(token.type || token) > -1; -}; - -CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) { - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - // Reset previous state if text or context changed too much - if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0])) - context.autoInsertedBrackets = 0; - context.autoInsertedRow = cursor.row; - context.autoInsertedLineEnd = bracket + line.substr(cursor.column); - context.autoInsertedBrackets++; -}; - -CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) { - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - if (!this.isMaybeInsertedClosing(cursor, line)) - context.maybeInsertedBrackets = 0; - context.maybeInsertedRow = cursor.row; - context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket; - context.maybeInsertedLineEnd = line.substr(cursor.column); - context.maybeInsertedBrackets++; -}; - -CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { - return context.autoInsertedBrackets > 0 && - cursor.row === context.autoInsertedRow && - bracket === context.autoInsertedLineEnd[0] && - line.substr(cursor.column) === context.autoInsertedLineEnd; -}; - -CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) { - return context.maybeInsertedBrackets > 0 && - cursor.row === context.maybeInsertedRow && - line.substr(cursor.column) === context.maybeInsertedLineEnd && - line.substr(0, cursor.column) == context.maybeInsertedLineStart; -}; - -CstyleBehaviour.popAutoInsertedClosing = function() { - context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1); - context.autoInsertedBrackets--; -}; - -CstyleBehaviour.clearMaybeInsertedClosing = function() { - if (context) { - context.maybeInsertedBrackets = 0; - context.maybeInsertedRow = -1; - } -}; - - - -oop.inherits(CstyleBehaviour, Behaviour); - -exports.CstyleBehaviour = CstyleBehaviour; -}); diff --git a/lib/ace/mode/behaviour/html.js b/lib/ace/mode/behaviour/html.js deleted file mode 100644 index 181655c07ee..00000000000 --- a/lib/ace/mode/behaviour/html.js +++ /dev/null @@ -1,46 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var XmlBehaviour = require("../behaviour/xml").XmlBehaviour; - -var HtmlBehaviour = function () { - - XmlBehaviour.call(this); - -}; - -oop.inherits(HtmlBehaviour, XmlBehaviour); - -exports.HtmlBehaviour = HtmlBehaviour; -}); diff --git a/lib/ace/mode/behaviour/xml.js b/lib/ace/mode/behaviour/xml.js deleted file mode 100644 index ae92e91b3c6..00000000000 --- a/lib/ace/mode/behaviour/xml.js +++ /dev/null @@ -1,214 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var Behaviour = require("../behaviour").Behaviour; -var TokenIterator = require("../../token_iterator").TokenIterator; -var lang = require("../../lib/lang"); - -function is(token, type) { - return token && token.type.lastIndexOf(type + ".xml") > -1; -} - -var XmlBehaviour = function () { - - this.add("string_dquotes", "insertion", function (state, action, editor, session, text) { - if (text == '"' || text == "'") { - var quote = text; - var selected = session.doc.getTextRange(editor.getSelectionRange()); - if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { - return { - text: quote + selected + quote, - selection: false - }; - } - - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - var rightChar = line.substring(cursor.column, cursor.column + 1); - var iterator = new TokenIterator(session, cursor.row, cursor.column); - var token = iterator.getCurrentToken(); - - if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) { - // Ignore input and move right one if we're typing over the closing quote. - return { - text: "", - selection: [1, 1] - }; - } - - if (!token) - token = iterator.stepBackward(); - - if (!token) - return; - - while (is(token, "tag-whitespace") || is(token, "whitespace")) { - token = iterator.stepBackward(); - } - var rightSpace = !rightChar || rightChar.match(/\s/); - if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) { - return { - text: quote + quote, - selection: [1, 1] - }; - } - } - }); - - this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { - var selected = session.doc.getTextRange(range); - if (!range.isMultiLine() && (selected == '"' || selected == "'")) { - var line = session.doc.getLine(range.start.row); - var rightChar = line.substring(range.start.column + 1, range.start.column + 2); - if (rightChar == selected) { - range.end.column++; - return range; - } - } - }); - - this.add("autoclosing", "insertion", function (state, action, editor, session, text) { - if (text == '>') { - var position = editor.getSelectionRange().start; - var iterator = new TokenIterator(session, position.row, position.column); - var token = iterator.getCurrentToken() || iterator.stepBackward(); - - // exit if we're not in a tag - if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value"))) - return; - - // exit if we're inside of a quoted attribute value - if (is(token, "reference.attribute-value")) - return; - if (is(token, "attribute-value")) { - var tokenEndColumn = iterator.getCurrentTokenColumn() + token.value.length; - if (position.column < tokenEndColumn) - return; - if (position.column == tokenEndColumn) { - var nextToken = iterator.stepForward(); - // TODO also handle non-closed string at the end of the line - if (nextToken && is(nextToken, "attribute-value")) - return; - iterator.stepBackward(); - } - } - - if (/^\s*>/.test(session.getLine(position.row).slice(position.column))) - return; - - // find tag name - while (!is(token, "tag-name")) { - token = iterator.stepBackward(); - if (token.value == "<") { - token = iterator.stepForward(); - break; - } - } - - var tokenRow = iterator.getCurrentTokenRow(); - var tokenColumn = iterator.getCurrentTokenColumn(); - - // exit if the tag is ending - if (is(iterator.stepBackward(), "end-tag-open")) - return; - - var element = token.value; - if (tokenRow == position.row) - element = element.substring(0, position.column - tokenColumn); - - if (this.voidElements.hasOwnProperty(element.toLowerCase())) - return; - - return { - text: ">" + "", - selection: [1, 1] - }; - } - }); - - this.add("autoindent", "insertion", function (state, action, editor, session, text) { - if (text == "\n") { - var cursor = editor.getCursorPosition(); - var line = session.getLine(cursor.row); - var iterator = new TokenIterator(session, cursor.row, cursor.column); - var token = iterator.getCurrentToken(); - - if (token && token.type.indexOf("tag-close") !== -1) { - if (token.value == "/>") - return; - //get tag name - while (token && token.type.indexOf("tag-name") === -1) { - token = iterator.stepBackward(); - } - - if (!token) { - return; - } - - var tag = token.value; - var row = iterator.getCurrentTokenRow(); - - //don't indent after closing tag - token = iterator.stepBackward(); - if (!token || token.type.indexOf("end-tag") !== -1) { - return; - } - - if (this.voidElements && !this.voidElements[tag]) { - var nextToken = session.getTokenAt(cursor.row, cursor.column+1); - var line = session.getLine(row); - var nextIndent = this.$getIndent(line); - var indent = nextIndent + session.getTabString(); - - if (nextToken && nextToken.value === "') { - var position = editor.getCursorPosition(); - var iterator = new TokenIterator(session, position.row, position.column); - var token = iterator.getCurrentToken(); - var atCursor = false; - var state = JSON.parse(state).pop(); - if ((token && token.value === '>') || state !== "StartTag") return; - if (!token || !hasType(token, 'meta.tag') && !(hasType(token, 'text') && token.value.match('/'))){ - do { - token = iterator.stepBackward(); - } while (token && (hasType(token, 'string') || hasType(token, 'keyword.operator') || hasType(token, 'entity.attribute-name') || hasType(token, 'text'))); - } else { - atCursor = true; - } - var previous = iterator.stepBackward(); - if (!token || !hasType(token, 'meta.tag') || (previous !== null && previous.value.match('/'))) { - return; - } - var tag = token.value.substring(1); - if (atCursor){ - var tag = tag.substring(0, position.column - token.start); - } - - return { - text: '>' + '', - selection: [1, 1] - }; - } - }); - - }; - oop.inherits(XQueryBehaviour, Behaviour); - - exports.XQueryBehaviour = XQueryBehaviour; -}); diff --git a/lib/ace/mode/bro.js b/lib/ace/mode/bro.js deleted file mode 100644 index fd9ff82eeb8..00000000000 --- a/lib/ace/mode/bro.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var BroHighlightRules = require("./bro_highlight_rules").BroHighlightRules; -// TODO: pick appropriate fold mode -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = BroHighlightRules; - this.foldingRules = new FoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - // this.lineCommentStart = ""#""; - // this.blockComment = {start: ""/*"", end: ""*/""}; - // Extra logic goes here. - this.$id = "ace/mode/bro"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/bro_highlight_rules.js b/lib/ace/mode/bro_highlight_rules.js deleted file mode 100644 index 6c36a839f75..00000000000 --- a/lib/ace/mode/bro_highlight_rules.js +++ /dev/null @@ -1,204 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* This file was autogenerated from Bro.tmLanguage (uuid: ) */ -/**************************************************************************************** - * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * - * fileTypes * - ****************************************************************************************/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var BroHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { - start: [{ - token: "punctuation.definition.comment.bro", - regex: /#/, - push: [{ - token: "comment.line.number-sign.bro", - regex: /$/, - next: "pop" - }, { - defaultToken: "comment.line.number-sign.bro" - }] - }, { - token: "keyword.control.bro", - regex: /\b(?:break|case|continue|else|for|if|return|switch|next|when|timeout|schedule)\b/ - }, { - token: [ - "meta.function.bro", - "meta.function.bro", - "storage.type.bro", - "meta.function.bro", - "entity.name.function.bro", - "meta.function.bro" - ], - regex: /^(\s*)(?:function|hook|event)(\s*)(.*)(\s*\()(.*)(\).*$)/ - }, { - token: "storage.type.bro", - regex: /\b(?:bool|enum|double|int|count|port|addr|subnet|any|file|interval|time|string|table|vector|set|record|pattern|hook)\b/ - }, { - token: "storage.modifier.bro", - regex: /\b(?:global|const|redef|local|&(?:optional|rotate_interval|rotate_size|add_func|del_func|expire_func|expire_create|expire_read|expire_write|persistent|synchronized|encrypt|mergeable|priority|group|type_column|log|error_handler))\b/ - }, { - token: "keyword.operator.bro", - regex: /\s*(?:\||&&|(?:>|<|!)=?|==)\s*|\b!?in\b/ - }, { - token: "constant.language.bro", - regex: /\b(?:T|F)\b/ - }, { - token: "constant.numeric.bro", - regex: /\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:(?:e|E)(?:\+|-)?[0-9]+)?)(?:\/(?:tcp|udp|icmp)|\s*(?:u?sec|min|hr|day)s?)?\b/ - }, { - token: "punctuation.definition.string.begin.bro", - regex: /"/, - push: [{ - token: "punctuation.definition.string.end.bro", - regex: /"/, - next: "pop" - }, { - include: "#string_escaped_char" - }, { - include: "#string_placeholder" - }, { - defaultToken: "string.quoted.double.bro" - }] - }, { - token: "punctuation.definition.string.begin.bro", - regex: /\//, - push: [{ - token: "punctuation.definition.string.end.bro", - regex: /\//, - next: "pop" - }, { - include: "#string_escaped_char" - }, { - include: "#string_placeholder" - }, { - defaultToken: "string.quoted.regex.bro" - }] - }, { - token: [ - "meta.preprocessor.bro.load", - "keyword.other.special-method.bro" - ], - regex: /^(\s*)(\@load(?:-sigs)?)\b/, - push: [{ - token: [], - regex: /(?=\#)|$/, - next: "pop" - }, { - defaultToken: "meta.preprocessor.bro.load" - }] - }, { - token: [ - "meta.preprocessor.bro.if", - "keyword.other.special-method.bro", - "meta.preprocessor.bro.if" - ], - regex: /^(\s*)(\@endif|\@if(?:n?def)?)(.*$)/, - push: [{ - token: [], - regex: /$/, - next: "pop" - }, { - defaultToken: "meta.preprocessor.bro.if" - }] - }], - "#disabled": [{ - token: "text", - regex: /^\s*\@if(?:n?def)?\b.*$/, - push: [{ - token: "text", - regex: /^\s*\@endif\b.*$/, - next: "pop" - }, { - include: "#disabled" - }, { - include: "#pragma-mark" - }], - comment: "eat nested preprocessor ifdefs" - }], - "#preprocessor-rule-other": [{ - token: [ - "text", - "meta.preprocessor.bro", - "meta.preprocessor.bro", - "text" - ], - regex: /^(\s*)(@if)((?:n?def)?)\b(.*?)(?:(?=)|$)/, - push: [{ - token: ["text", "meta.preprocessor.bro", "text"], - regex: /^(\s*)(@endif)\b(.*$)/, - next: "pop" - }, { - include: "$base" - }] - }], - "#string_escaped_char": [{ - token: "constant.character.escape.bro", - regex: /\\(?:\\|[abefnprtv'"?]|[0-3]\d{,2}|[4-7]\d?|x[a-fA-F0-9]{,2})/ - }, { - token: "invalid.illegal.unknown-escape.bro", - regex: /\\./ - }], - "#string_placeholder": [{ - token: "constant.other.placeholder.bro", - regex: /%(?:\d+\$)?[#0\- +']*[,;:_]?(?:-?\d+|\*(?:-?\d+\$)?)?(?:\.(?:-?\d+|\*(?:-?\d+\$)?)?)?(?:hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)?[diouxXDOUeEfFgGaACcSspn%]/ - }, { - token: "invalid.illegal.placeholder.bro", - regex: /%/ - }] - }; - - this.normalizeRules(); -}; - -BroHighlightRules.metaData = { - fileTypes: ["bro"], - foldingStartMarker: "^(\\@if(n?def)?)", - foldingStopMarker: "^\\@endif", - keyEquivalent: "@B", - name: "Bro", - scopeName: "source.bro" -}; - - -oop.inherits(BroHighlightRules, TextHighlightRules); - -exports.BroHighlightRules = BroHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/c9search.js b/lib/ace/mode/c9search.js deleted file mode 100644 index 3286456a79d..00000000000 --- a/lib/ace/mode/c9search.js +++ /dev/null @@ -1,67 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var C9SearchHighlightRules = require("./c9search_highlight_rules").C9SearchHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var C9StyleFoldMode = require("./folding/c9search").FoldMode; - -var Mode = function() { - this.HighlightRules = C9SearchHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.foldingRules = new C9StyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/c9search"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); diff --git a/lib/ace/mode/c_cpp.js b/lib/ace/mode/c_cpp.js deleted file mode 100644 index a2dc133f412..00000000000 --- a/lib/ace/mode/c_cpp.js +++ /dev/null @@ -1,101 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var c_cppHighlightRules = require("./c_cpp_highlight_rules").c_cppHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = c_cppHighlightRules; - - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } else if (state == "doc-start") { - if (endState == "start") { - return ""; - } - var match = line.match(/^\s*(\/?)\*/); - if (match) { - if (match[1]) { - indent += " "; - } - indent += "* "; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/c_cpp"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/c_cpp_highlight_rules.js b/lib/ace/mode/c_cpp_highlight_rules.js deleted file mode 100644 index 82c0a3c3759..00000000000 --- a/lib/ace/mode/c_cpp_highlight_rules.js +++ /dev/null @@ -1,199 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -// used by objective-c -var cFunctions = exports.cFunctions = "\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b"; - -var c_cppHighlightRules = function() { - - var keywordControls = ( - "break|case|continue|default|do|else|for|goto|if|_Pragma|" + - "return|switch|while|catch|operator|try|throw|using" - ); - - var storageType = ( - "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + - "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|" + - "class|wchar_t|template|char16_t|char32_t" - ); - - var storageModifiers = ( - "const|extern|register|restrict|static|volatile|inline|private|" + - "protected|public|friend|explicit|virtual|export|mutable|typename|" + - "constexpr|new|delete|alignas|alignof|decltype|noexcept|thread_local" - ); - - var keywordOperators = ( - "and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|" + - "const_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace" - ); - - var builtinConstants = ( - "NULL|true|false|TRUE|FALSE|nullptr" - ); - - var keywordMapper = this.$keywords = this.createKeywordMapper({ - "keyword.control" : keywordControls, - "storage.type" : storageType, - "storage.modifier" : storageModifiers, - "keyword.operator" : keywordOperators, - "variable.language": "this", - "constant.language": builtinConstants - }, "identifier"); - - var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b"; - 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; - var formatRe = "%" - + /(\d+\$)?/.source // field (argument #) - + /[#0\- +']*/.source // flags - + /[,;:_]?/.source // separator character (AltiVec) - + /((-?\d+)|\*(-?\d+\$)?)?/.source // minimum field width - + /(\.((-?\d+)|\*(-?\d+\$)?)?)?/.source // precision - + /(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)?/.source // length modifier - + /(\[[^"\]]+\]|[diouxXDOUeEfFgGaACcSspn%])/.source; // conversion type - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { - "start" : [ - { - token : "comment", - regex : "//$", - next : "start" - }, { - token : "comment", - regex : "//", - next : "singleLineComment" - }, - DocCommentHighlightRules.getStartRule("doc-start"), - { - token : "comment", // multi line comment - regex : "\\/\\*", - next : "comment" - }, { - token : "string", // character - regex : "'(?:" + escapeRe + "|.)?'" - }, { - token : "string.start", - regex : '"', - stateName: "qqstring", - next: [ - { token: "string", regex: /\\\s*$/, next: "qqstring" }, - { token: "constant.language.escape", regex: escapeRe }, - { token: "constant.language.escape", regex: formatRe }, - { token: "string.end", regex: '"|$', next: "start" }, - { defaultToken: "string"} - ] - }, { - token : "string.start", - regex : 'R"\\(', - stateName: "rawString", - next: [ - { token: "string.end", regex: '\\)"', next: "start" }, - { defaultToken: "string"} - ] - }, { - token : "constant.numeric", // hex - regex : "0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b" - }, { - token : "keyword", // pre-compiler directives - regex : "#\\s*(?:include|import|pragma|line|define|undef)\\b", - next : "directive" - }, { - token : "keyword", // special case pre-compiler directive - regex : "#\\s*(?:endif|if|ifdef|else|elif|ifndef)\\b" - }, { - token : "support.function.C99.c", - regex : cFunctions - }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*" - }, { - token : "keyword.operator", - regex : /--|\+\+|<<=|>>=|>>>=|<>|&&|\|\||\?:|[*%\/+\-&\^|~!<>=]=?/ - }, { - token : "punctuation.operator", - regex : "\\?|\\:|\\,|\\;|\\." - }, { - token : "paren.lparen", - regex : "[[({]" - }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" - } - ], - "comment" : [ - { - token : "comment", // closing comment - regex : "\\*\\/", - next : "start" - }, { - defaultToken : "comment" - } - ], - "singleLineComment" : [ - { - token : "comment", - regex : /\\$/, - next : "singleLineComment" - }, { - token : "comment", - regex : /$/, - next : "start" - }, { - defaultToken: "comment" - } - ], - "directive" : [ - { - token : "constant.other.multiline", - regex : /\\/ - }, - { - token : "constant.other.multiline", - regex : /.*\\/ - }, - { - token : "constant.other", - regex : "\\s*<.+?>", - next : "start" - }, - { - token : "constant.other", // single line - regex : '\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]', - next : "start" - }, - { - token : "constant.other", // single line - regex : "\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']", - next : "start" - }, - // "\" implies multiline, while "/" implies comment - { - token : "constant.other", - regex : /[^\\\/]+/, - next : "start" - } - ] - }; - - this.embedRules(DocCommentHighlightRules, "doc-", - [ DocCommentHighlightRules.getEndRule("start") ]); - this.normalizeRules(); -}; - -oop.inherits(c_cppHighlightRules, TextHighlightRules); - -exports.c_cppHighlightRules = c_cppHighlightRules; -}); diff --git a/lib/ace/mode/cirru.js b/lib/ace/mode/cirru.js deleted file mode 100644 index 75a4d0c407a..00000000000 --- a/lib/ace/mode/cirru.js +++ /dev/null @@ -1,52 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2014, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var CirruHighlightRules = require("./cirru_highlight_rules").CirruHighlightRules; -var CoffeeFoldMode = require("./folding/coffee").FoldMode; - -var Mode = function() { - this.HighlightRules = CirruHighlightRules; - this.foldingRules = new CoffeeFoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "--"; - this.$id = "ace/mode/cirru"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/cirru_highlight_rules.js b/lib/ace/mode/cirru_highlight_rules.js deleted file mode 100644 index de283369325..00000000000 --- a/lib/ace/mode/cirru_highlight_rules.js +++ /dev/null @@ -1,125 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2014, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -// see http://cirru.org for more about this language -var CirruHighlightRules = function() { - this.$rules = { - start: [{ - token: 'constant.numeric', - regex: /[\d\.]+/ - }, { - token: 'comment.line.double-dash', - regex: /--/, - next: 'comment' - }, { - token: 'storage.modifier', - regex: /\(/ - }, { - token: 'storage.modifier', - regex: /,/, - next: 'line' - }, { - token: 'support.function', - regex: /[^\(\)"\s]+/, - next: 'line' - }, { - token: 'string.quoted.double', - regex: /"/, - next: 'string' - }, { - token: 'storage.modifier', - regex: /\)/ - }], - comment: [{ - token: 'comment.line.double-dash', - regex: / +[^\n]+/, - next: 'start' - }], - string: [{ - token: 'string.quoted.double', - regex: /"/, - next: 'line' - }, { - token: 'constant.character.escape', - regex: /\\/, - next: 'escape' - }, { - token: 'string.quoted.double', - regex: /[^\\"]+/ - }], - escape: [{ - token: 'constant.character.escape', - regex: /./, - next: 'string' - }], - line: [{ - token: 'constant.numeric', - regex: /[\d\.]+/ - }, { - token: 'markup.raw', - regex: /^\s*/, - next: 'start' - }, { - token: 'storage.modifier', - regex: /\$/, - next: 'start' - }, { - token: 'variable.parameter', - regex: /[^\(\)"\s]+/ - }, { - token: 'storage.modifier', - regex: /\(/, - next: 'start' - }, { - token: 'storage.modifier', - regex: /\)/ - }, { - token: 'markup.raw', - regex: /^ */, - next: 'start' - }, { - token: 'string.quoted.double', - regex: /"/, - next: 'string' - }] - }; - -}; - -oop.inherits(CirruHighlightRules, TextHighlightRules); - -exports.CirruHighlightRules = CirruHighlightRules; -}); diff --git a/lib/ace/mode/clojure.js b/lib/ace/mode/clojure.js deleted file mode 100644 index 6bb9b0ae01c..00000000000 --- a/lib/ace/mode/clojure.js +++ /dev/null @@ -1,129 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var ClojureHighlightRules = require("./clojure_highlight_rules").ClojureHighlightRules; -var MatchingParensOutdent = require("./matching_parens_outdent").MatchingParensOutdent; - -var Mode = function() { - this.HighlightRules = ClojureHighlightRules; - this.$outdent = new MatchingParensOutdent(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = ";"; - this.minorIndentFunctions = ["defn", "defn-", "defmacro", "def", "deftest", "testing"]; - - this.$toIndent = function(str) { - return str.split('').map(function(ch) { - if (/\s/.exec(ch)) { - return ch; - } else { - return ' '; - } - }).join(''); - }; - - this.$calculateIndent = function(line, tab) { - var baseIndent = this.$getIndent(line); - var delta = 0; - var isParen, ch; - // Walk back from end of line, find matching braces - for (var i = line.length - 1; i >= 0; i--) { - ch = line[i]; - if (ch === '(') { - delta--; - isParen = true; - } else if (ch === '(' || ch === '[' || ch === '{') { - delta--; - isParen = false; - } else if (ch === ')' || ch === ']' || ch === '}') { - delta++; - } - if (delta < 0) { - break; - } - } - if (delta < 0 && isParen) { - // Were more brackets opened than closed and was a ( left open? - i += 1; - var iBefore = i; - var fn = ''; - while (true) { - ch = line[i]; - if (ch === ' ' || ch === '\t') { - if(this.minorIndentFunctions.indexOf(fn) !== -1) { - return this.$toIndent(line.substring(0, iBefore - 1) + tab); - } else { - return this.$toIndent(line.substring(0, i + 1)); - } - } else if (ch === undefined) { - return this.$toIndent(line.substring(0, iBefore - 1) + tab); - } - fn += line[i]; - i++; - } - } else if(delta < 0 && !isParen) { - // Were more brackets openend than closed and was it not a (? - return this.$toIndent(line.substring(0, i+1)); - } else if(delta > 0) { - // Mere more brackets closed than opened? Outdent. - baseIndent = baseIndent.substring(0, baseIndent.length - tab.length); - return baseIndent; - } else { - // Were they nicely matched? Just indent like line before. - return baseIndent; - } - }; - - this.getNextLineIndent = function(state, line, tab) { - return this.$calculateIndent(line, tab); - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/clojure"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/cobol.js b/lib/ace/mode/cobol.js deleted file mode 100644 index 3b3259853d9..00000000000 --- a/lib/ace/mode/cobol.js +++ /dev/null @@ -1,53 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var CobolHighlightRules = require("./cobol_highlight_rules").CobolHighlightRules; - -var Mode = function() { - this.HighlightRules = CobolHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "*"; - - this.$id = "ace/mode/cobol"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); diff --git a/lib/ace/mode/cobol_highlight_rules.js b/lib/ace/mode/cobol_highlight_rules.js deleted file mode 100644 index 36335c932dd..00000000000 --- a/lib/ace/mode/cobol_highlight_rules.js +++ /dev/null @@ -1,100 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var CobolHighlightRules = function() { -var keywords = "ACCEPT|MERGE|SUM|ADD||MESSAGE|TABLE|ADVANCING|MODE|TAPE|" + -"AFTER|MULTIPLY|TEST|ALL|NEGATIVE|TEXT|ALPHABET|NEXT|THAN|" + -"ALSO|NO|THEN|ALTERNATE|NOT|THROUGH|AND|NUMBER|THRU|ANY|OCCURS|" + -"TIME|ARE|OF|TO|AREA|OFF|TOP||ASCENDING|OMITTED|TRUE|ASSIGN|ON|TYPE|AT|OPEN|" + -"UNIT|AUTHOR|OR|UNTIL|BEFORE|OTHER|UP|BLANK|OUTPUT|USE|BLOCK|PAGE|USING|BOTTOM|" + -"PERFORM|VALUE|BY|PIC|VALUES|CALL|PICTURE|WHEN|CANCEL|PLUS|WITH|CD|POINTER|WRITE|" + -"CHARACTER|POSITION||ZERO|CLOSE|POSITIVE|ZEROS|COLUMN|PROCEDURE|ZEROES|COMMA|PROGRAM|" + -"COMMON|PROGRAM-ID|COMMUNICATION|QUOTE|COMP|RANDOM|COMPUTE|READ|CONTAINS|RECEIVE|CONFIGURATION|" + -"RECORD|CONTINUE|REDEFINES|CONTROL|REFERENCE|COPY|REMAINDER|COUNT|REPLACE|DATA|REPORT|DATE|RESERVE|" + -"DAY|RESET|DELETE|RETURN|DESTINATION|REWIND|DISABLE|REWRITE|DISPLAY|RIGHT|DIVIDE|RUN|DOWN|SAME|" + -"ELSE|SEARCH|ENABLE|SECTION|END|SELECT|ENVIRONMENT|SENTENCE|EQUAL|SET|ERROR|SIGN|EXIT|SEQUENTIAL|" + -"EXTERNAL|SIZE|FLASE|SORT|FILE|SOURCE|LENGTH|SPACE|LESS|STANDARD|LIMIT|START|LINE|STOP|LOCK|STRING|LOW-VALUE|SUBTRACT"; - - var builtinConstants = ( - "true|false|null" - ); - - var builtinFunctions = ( - "count|min|max|avg|sum|rank|now|coalesce|main" - ); - - var keywordMapper = this.createKeywordMapper({ - "support.function": builtinFunctions, - "keyword": keywords, - "constant.language": builtinConstants - }, "identifier", true); - - this.$rules = { - "start" : [ { - token : "comment", - regex : "\\*.*$" - }, { - token : "string", // " string - regex : '".*?"' - }, { - token : "string", // ' string - regex : "'.*?'" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "keyword.operator", - regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|=" - }, { - token : "paren.lparen", - regex : "[\\(]" - }, { - token : "paren.rparen", - regex : "[\\)]" - }, { - token : "text", - regex : "\\s+" - } ] - }; -}; - -oop.inherits(CobolHighlightRules, TextHighlightRules); - -exports.CobolHighlightRules = CobolHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/coffee.js b/lib/ace/mode/coffee.js deleted file mode 100644 index 9782fc7181f..00000000000 --- a/lib/ace/mode/coffee.js +++ /dev/null @@ -1,116 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var Rules = require("./coffee_highlight_rules").CoffeeHighlightRules; -var Outdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var FoldMode = require("./folding/coffee").FoldMode; -var Range = require("../range").Range; -var TextMode = require("./text").Mode; -var WorkerClient = require("../worker/worker_client").WorkerClient; -var oop = require("../lib/oop"); - -function Mode() { - this.HighlightRules = Rules; - this.$outdent = new Outdent(); - this.foldingRules = new FoldMode(); -} - -oop.inherits(Mode, TextMode); - -(function() { - - /*: - [({[=:] # Opening parentheses or brackets - |[-=]> # OR single or double arrow - |\b(?: # OR one of these words: - else # else - |try # OR try - |(?:swi|ca)tch # OR catch, optionally followed by: - (?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)? # a variable - |finally # OR finally - ))\s*$ # all as the last thing on a line (allowing trailing space) - | # ---- OR ---- : - ^\s* # a line starting with optional space - (else\b\s*)? # followed by an optional "else" - (?: # followed by one of the following: - if # if - |for # OR for - |while # OR while - |loop # OR loop - )\b # (as a word) - (?!.*\bthen\b) # ... but NOT followed by "then" on the line - */ - 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)/; - - this.lineCommentStart = "#"; - this.blockComment = {start: "###", end: "###"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - var tokens = this.getTokenizer().getLineTokens(line, state).tokens; - - if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') && - state === 'start' && indenter.test(line)) - indent += tab; - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.createWorker = function(session) { - var worker = new WorkerClient(["ace"], "ace/mode/coffee_worker", "Worker"); - worker.attachToDocument(session.getDocument()); - - worker.on("annotate", function(e) { - session.setAnnotations(e.data); - }); - - worker.on("terminate", function() { - session.clearAnnotations(); - }); - - return worker; - }; - - this.$id = "ace/mode/coffee"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); diff --git a/lib/ace/mode/coldfusion.js b/lib/ace/mode/coldfusion.js deleted file mode 100644 index 0b4ea449173..00000000000 --- a/lib/ace/mode/coldfusion.js +++ /dev/null @@ -1,61 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var HtmlMode = require("./html").Mode; -var ColdfusionHighlightRules = require("./coldfusion_highlight_rules").ColdfusionHighlightRules; - -var 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("|"); - -var Mode = function() { - HtmlMode.call(this); - - this.HighlightRules = ColdfusionHighlightRules; -}; -oop.inherits(Mode, HtmlMode); - -(function() { - - // mix with html void elements - this.voidElements = oop.mixin(lang.arrayToMap(voidElements), this.voidElements); - - this.getNextLineIndent = function(state, line, tab) { - return this.$getIndent(line); - }; - - this.$id = "ace/mode/coldfusion"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/coldfusion_highlight_rules.js b/lib/ace/mode/coldfusion_highlight_rules.js deleted file mode 100644 index 469de2924c0..00000000000 --- a/lib/ace/mode/coldfusion_highlight_rules.js +++ /dev/null @@ -1,86 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; -var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; - -var ColdfusionHighlightRules = function() { - HtmlHighlightRules.call(this); - this.$rules.tag[2].token = function (start, tag) { - var group = tag.slice(0,2) == "cf" ? "keyword" : "meta.tag"; - return ["meta.tag.punctuation." + (start == "<" ? "" : "end-") + "tag-open.xml", - group + ".tag-name.xml"]; - }; - - var jsAndCss = Object.keys(this.$rules).filter(function(x) { - return /^(js|css)-/.test(x); - }); - this.embedRules({ - cfmlComment: [ - { regex: "", token: "comment.end", next: "pop"}, - { defaultToken: "comment"} - ] - }, "", [ - { regex: "", " ", "fg"].join("\n"), session.toString()); - }, - - "test: next line indent should be the same as the current line indent" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " abc")); - assert.equal("", this.mode.getNextLineIndent("start", "abc")); - assert.equal("\t", this.mode.getNextLineIndent("start", "\tabc")); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/mode/csharp.js b/lib/ace/mode/csharp.js deleted file mode 100644 index a3b2964f944..00000000000 --- a/lib/ace/mode/csharp.js +++ /dev/null @@ -1,61 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var CSharpHighlightRules = require("./csharp_highlight_rules").CSharpHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/csharp").FoldMode; - -var Mode = function() { - this.HighlightRules = CSharpHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - - this.createWorker = function(session) { - return null; - }; - - this.$id = "ace/mode/csharp"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/csound_document.js b/lib/ace/mode/csound_document.js deleted file mode 100644 index a10d7d5ecfb..00000000000 --- a/lib/ace/mode/csound_document.js +++ /dev/null @@ -1,14 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var CsoundDocumentHighlightRules = require("./csound_document_highlight_rules").CsoundDocumentHighlightRules; - -var Mode = function() { - this.HighlightRules = CsoundDocumentHighlightRules; -}; -oop.inherits(Mode, TextMode); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/csound_orchestra.js b/lib/ace/mode/csound_orchestra.js deleted file mode 100644 index 4f712911eba..00000000000 --- a/lib/ace/mode/csound_orchestra.js +++ /dev/null @@ -1,21 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var CsoundOrchestraHighlightRules = require("./csound_orchestra_highlight_rules").CsoundOrchestraHighlightRules; - -var Mode = function() { - this.HighlightRules = CsoundOrchestraHighlightRules; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = ";"; - this.blockComment = {start: "/*", end: "*/"}; - -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/csound_score.js b/lib/ace/mode/csound_score.js deleted file mode 100644 index 2abb00cd0e4..00000000000 --- a/lib/ace/mode/csound_score.js +++ /dev/null @@ -1,21 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var CsoundScoreHighlightRules = require("./csound_score_highlight_rules").CsoundScoreHighlightRules; - -var Mode = function() { - this.HighlightRules = CsoundScoreHighlightRules; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = ";"; - this.blockComment = {start: "/*", end: "*/"}; - -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/csp.js b/lib/ace/mode/csp.js deleted file mode 100644 index 529bb735406..00000000000 --- a/lib/ace/mode/csp.js +++ /dev/null @@ -1,53 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { - "use strict"; - - var TextMode = require("./text").Mode; - var CspHighlightRules = require("./csp_highlight_rules").CspHighlightRules; - var oop = require("../lib/oop"); - - var Mode = function() { - this.HighlightRules = CspHighlightRules; - }; - - oop.inherits(Mode, TextMode); - - (function() { - this.$id = "ace/mode/csp"; - }).call(Mode.prototype); - - exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/csp_highlight_rules.js b/lib/ace/mode/csp_highlight_rules.js deleted file mode 100644 index 19f4786878f..00000000000 --- a/lib/ace/mode/csp_highlight_rules.js +++ /dev/null @@ -1,70 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - EXPLANATION - - This highlight rules were created to help developer spot typos when working - with Content-Security-Policy (CSP). See: - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/ - */ - -define(function(require, exports, module) { - "use strict"; - - var oop = require("../lib/oop"); - var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - - var CspHighlightRules = function() { - var keywordMapper = this.createKeywordMapper({ - "constant.language": "child-src|connect-src|default-src|font-src|frame-src|img-src|manifest-src|media-src|object-src" - + "|script-src|style-src|worker-src|base-uri|plugin-types|sandbox|disown-opener|form-action|frame-ancestors|report-uri" - + "|report-to|upgrade-insecure-requests|block-all-mixed-content|require-sri-for|reflected-xss|referrer|policy-uri", - "variable": "'none'|'self'|'unsafe-inline'|'unsafe-eval'|'strict-dynamic'|'unsafe-hashed-attributes'" - }, "identifier", true); - - this.$rules = { - start: [{ - token: "string.link", - regex: /https?:[^;\s]*/ - }, { - token: "operator.punctuation", - regex: /;/ - }, { - token: keywordMapper, - regex: /[^\s;]+/ - }] - }; - }; - - oop.inherits(CspHighlightRules, TextHighlightRules); - - exports.CspHighlightRules = CspHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/css.js b/lib/ace/mode/css.js deleted file mode 100644 index cafa502cf13..00000000000 --- a/lib/ace/mode/css.js +++ /dev/null @@ -1,106 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var WorkerClient = require("../worker/worker_client").WorkerClient; -var CssCompletions = require("./css_completions").CssCompletions; -var CssBehaviour = require("./behaviour/css").CssBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = CssHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CssBehaviour(); - this.$completer = new CssCompletions(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.foldingRules = "cStyle"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - // ignore braces in comments - var tokens = this.getTokenizer().getLineTokens(line, state).tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - var match = line.match(/^.*\{\s*$/); - if (match) { - indent += tab; - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.getCompletions = function(state, session, pos, prefix) { - return this.$completer.getCompletions(state, session, pos, prefix); - }; - - this.createWorker = function(session) { - var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker"); - worker.attachToDocument(session.getDocument()); - - worker.on("annotate", function(e) { - session.setAnnotations(e.data); - }); - - worker.on("terminate", function() { - session.clearAnnotations(); - }); - - return worker; - }; - - this.$id = "ace/mode/css"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); diff --git a/lib/ace/mode/css/csslint.js b/lib/ace/mode/css/csslint.js index fec652802a2..fed22bd8623 100644 --- a/lib/ace/mode/css/csslint.js +++ b/lib/ace/mode/css/csslint.js @@ -1,7 +1,7 @@ -define(function(require, exports, module) { +define([], function(require, exports, module) { /*! -CSSLint -Copyright (c) 2014 Nicole Sullivan and Nicholas C. Zakas. All rights reserved. +CSSLint v1.0.5 +Copyright (c) 2021 Nicole Sullivan and Nicholas C. Zakas. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal @@ -22,10 +22,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* Build: v0.10.0 22-July-2014 01:17:52 */ + +var CSSLint = (function(){ + var module = module || {}, + exports = exports || {}; + /*! Parser-Lib -Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved. +Copyright (c) 2009-2016 Nicholas C. Zakas. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -44,4069 +48,3835 @@ 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. - */ -/* Version v0.2.5, Build time: 7-May-2014 03:37:38 */ -var parserlib = {}; -(function(){ +/* Version v1.1.2, Build time: 8-March-2021 19:42:03 */ +var parserlib = (function () { +var require; +require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i). + * @namespace parserlib.css + * @class Combinator + * @extends parserlib.util.SyntaxUnit * @constructor + * @param {String} text The text representation of the unit. + * @param {int} line The line of text on which the unit resides. + * @param {int} col The column of text on which the unit resides. */ -function EventTarget(){ +function Combinator(text, line, col) { + + SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE); /** - * The array of listeners for various events. - * @type Object - * @property _listeners - * @private + * The type of modifier. + * @type String + * @property type */ - this._listeners = {}; + this.type = "unknown"; + + // pretty simple + if (/^\s+$/.test(text)) { + this.type = "descendant"; + } else if (text === ">") { + this.type = "child"; + } else if (text === "+") { + this.type = "adjacent-sibling"; + } else if (text === "~") { + this.type = "sibling"; + } + } -EventTarget.prototype = { +Combinator.prototype = new SyntaxUnit(); +Combinator.prototype.constructor = Combinator; - //restore constructor - constructor: EventTarget, - /** - * Adds a listener for a given event type. - * @param {String} type The type of event to add a listener for. - * @param {Function} listener The function to call when the event occurs. - * @return {void} - * @method addListener - */ - addListener: function(type, listener){ - if (!this._listeners[type]){ - this._listeners[type] = []; +},{"../util/SyntaxUnit":26,"./Parser":6}],3:[function(require,module,exports){ +"use strict"; + +module.exports = Matcher; + +var StringReader = require("../util/StringReader"); +var SyntaxError = require("../util/SyntaxError"); + +/** + * This class implements a combinator library for matcher functions. + * The combinators are described at: + * https://developer.mozilla.org/en-US/docs/Web/CSS/Value_definition_syntax#Component_value_combinators + */ +function Matcher(matchFunc, toString) { + this.match = function(expression) { + // Save/restore marks to ensure that failed matches always restore + // the original location in the expression. + var result; + expression.mark(); + result = matchFunc(expression); + if (result) { + expression.drop(); + } else { + expression.restore(); } + return result; + }; + this.toString = typeof toString === "function" ? toString : function() { + return toString; + }; +} - this._listeners[type].push(listener); - }, +/** Precedence table of combinators. */ +Matcher.prec = { + MOD: 5, + SEQ: 4, + ANDAND: 3, + OROR: 2, + ALT: 1 +}; - /** - * Fires an event based on the passed-in object. - * @param {Object|String} event An object with at least a 'type' attribute - * or a string indicating the event name. - * @return {void} - * @method fire - */ - fire: function(event){ - if (typeof event == "string"){ - event = { type: event }; +/** Simple recursive-descent grammar to build matchers from strings. */ +Matcher.parse = function(str) { + var reader, eat, expr, oror, andand, seq, mod, term, result; + reader = new StringReader(str); + eat = function(matcher) { + var result = reader.readMatch(matcher); + if (result === null) { + throw new SyntaxError( + "Expected " + matcher, reader.getLine(), reader.getCol()); } - if (typeof event.target != "undefined"){ - event.target = this; + return result; + }; + expr = function() { + // expr = oror (" | " oror)* + var m = [ oror() ]; + while (reader.readMatch(" | ") !== null) { + m.push(oror()); + } + return m.length === 1 ? m[0] : Matcher.alt.apply(Matcher, m); + }; + oror = function() { + // oror = andand ( " || " andand)* + var m = [ andand() ]; + while (reader.readMatch(" || ") !== null) { + m.push(andand()); + } + return m.length === 1 ? m[0] : Matcher.oror.apply(Matcher, m); + }; + andand = function() { + // andand = seq ( " && " seq)* + var m = [ seq() ]; + while (reader.readMatch(" && ") !== null) { + m.push(seq()); + } + return m.length === 1 ? m[0] : Matcher.andand.apply(Matcher, m); + }; + seq = function() { + // seq = mod ( " " mod)* + var m = [ mod() ]; + while (reader.readMatch(/^ (?![&|\]])/) !== null) { + m.push(mod()); + } + return m.length === 1 ? m[0] : Matcher.seq.apply(Matcher, m); + }; + mod = function() { + // mod = term ( "?" | "*" | "+" | "#" | "{,}" )? + var m = term(); + if (reader.readMatch("?") !== null) { + return m.question(); + } else if (reader.readMatch("*") !== null) { + return m.star(); + } else if (reader.readMatch("+") !== null) { + return m.plus(); + } else if (reader.readMatch("#") !== null) { + return m.hash(); + } else if (reader.readMatch(/^\{\s*/) !== null) { + var min = eat(/^\d+/); + eat(/^\s*,\s*/); + var max = eat(/^\d+/); + eat(/^\s*\}/); + return m.braces(Number(min), Number(max)); + } + return m; + }; + term = function() { + // term = | literal | "[ " expression " ]" + if (reader.readMatch("[ ") !== null) { + var m = expr(); + eat(" ]"); + return m; } + return Matcher.fromType(eat(/^[^ ?*+#{]+/)); + }; + result = expr(); + if (!reader.eof()) { + throw new SyntaxError( + "Expected end of string", reader.getLine(), reader.getCol()); + } + return result; +}; - if (typeof event.type == "undefined"){ - throw new Error("Event object missing 'type' property."); +/** + * Convert a string to a matcher (parsing simple alternations), + * or do nothing if the argument is already a matcher. + */ +Matcher.cast = function(m) { + if (m instanceof Matcher) { + return m; + } + return Matcher.parse(m); +}; + +/** + * Create a matcher for a single type. + */ +Matcher.fromType = function(type) { + // Late require of ValidationTypes to break a dependency cycle. + var ValidationTypes = require("./ValidationTypes"); + return new Matcher(function(expression) { + return expression.hasNext() && ValidationTypes.isType(expression, type); + }, type); +}; + +/** + * Create a matcher for one or more juxtaposed words, which all must + * occur, in the given order. + */ +Matcher.seq = function() { + var ms = Array.prototype.slice.call(arguments).map(Matcher.cast); + if (ms.length === 1) { + return ms[0]; + } + return new Matcher(function(expression) { + var i, result = true; + for (i = 0; result && i < ms.length; i++) { + result = ms[i].match(expression); + } + return result; + }, function(prec) { + var p = Matcher.prec.SEQ; + var s = ms.map(function(m) { + return m.toString(p); + }).join(" "); + if (prec > p) { + s = "[ " + s + " ]"; } + return s; + }); +}; - if (this._listeners[event.type]){ +/** + * Create a matcher for one or more alternatives, where exactly one + * must occur. + */ +Matcher.alt = function() { + var ms = Array.prototype.slice.call(arguments).map(Matcher.cast); + if (ms.length === 1) { + return ms[0]; + } + return new Matcher(function(expression) { + var i, result = false; + for (i = 0; !result && i < ms.length; i++) { + result = ms[i].match(expression); + } + return result; + }, function(prec) { + var p = Matcher.prec.ALT; + var s = ms.map(function(m) { + return m.toString(p); + }).join(" | "); + if (prec > p) { + s = "[ " + s + " ]"; + } + return s; + }); +}; - //create a copy of the array and use that so listeners can't chane - var listeners = this._listeners[event.type].concat(); - for (var i=0, len=listeners.length; i < len; i++){ - listeners[i].call(this, event); - } +/** + * Create a matcher for two or more options. This implements the + * double bar (||) and double ampersand (&&) operators, as well as + * variants of && where some of the alternatives are optional. + * This will backtrack through even successful matches to try to + * maximize the number of items matched. + */ +Matcher.many = function(required) { + var ms = Array.prototype.slice.call(arguments, 1).reduce(function(acc, v) { + if (v.expand) { + // Insert all of the options for the given complex rule as + // individual options. + var ValidationTypes = require("./ValidationTypes"); + acc.push.apply(acc, ValidationTypes.complex[v.expand].options); + } else { + acc.push(Matcher.cast(v)); } - }, + return acc; + }, []); - /** - * Removes a listener for a given event type. - * @param {String} type The type of event to remove a listener from. - * @param {Function} listener The function to remove from the event. - * @return {void} - * @method removeListener - */ - removeListener: function(type, listener){ - if (this._listeners[type]){ - var listeners = this._listeners[type]; - for (var i=0, len=listeners.length; i < len; i++){ - if (listeners[i] === listener){ - listeners.splice(i, 1); - break; + if (required === true) { + required = ms.map(function() { + return true; + }); + } + + var result = new Matcher(function(expression) { + var seen = [], max = 0, pass = 0; + var success = function(matchCount) { + if (pass === 0) { + max = Math.max(matchCount, max); + return matchCount === ms.length; + } else { + return matchCount === max; + } + }; + var tryMatch = function(matchCount) { + for (var i = 0; i < ms.length; i++) { + if (seen[i]) { + continue; + } + expression.mark(); + if (ms[i].match(expression)) { + seen[i] = true; + // Increase matchCount iff this was a required element + // (or if all the elements are optional) + if (tryMatch(matchCount + (required === false || required[i] ? 1 : 0))) { + expression.drop(); + return true; + } + // Backtrack: try *not* matching using this rule, and + // let's see if it leads to a better overall match. + expression.restore(); + seen[i] = false; + } else { + expression.drop(); } } + return success(matchCount); + }; + if (!tryMatch(0)) { + // Couldn't get a complete match, retrace our steps to make the + // match with the maximum # of required elements. + pass++; + tryMatch(0); + } + + if (required === false) { + return max > 0; + } + // Use finer-grained specification of which matchers are required. + for (var i = 0; i < ms.length; i++) { + if (required[i] && !seen[i]) { + return false; + } + } + return true; + }, function(prec) { + var p = required === false ? Matcher.prec.OROR : Matcher.prec.ANDAND; + var s = ms.map(function(m, i) { + if (required !== false && !required[i]) { + return m.toString(Matcher.prec.MOD) + "?"; + } + return m.toString(p); + }).join(required === false ? " || " : " && "); + if (prec > p) { + s = "[ " + s + " ]"; + } + return s; + }); + result.options = ms; + return result; +}; + +/** + * Create a matcher for two or more options, where all options are + * mandatory but they may appear in any order. + */ +Matcher.andand = function() { + var args = Array.prototype.slice.call(arguments); + args.unshift(true); + return Matcher.many.apply(Matcher, args); +}; +/** + * Create a matcher for two or more options, where options are + * optional and may appear in any order, but at least one must be + * present. + */ +Matcher.oror = function() { + var args = Array.prototype.slice.call(arguments); + args.unshift(false); + return Matcher.many.apply(Matcher, args); +}; +/** Instance methods on Matchers. */ +Matcher.prototype = { + constructor: Matcher, + // These are expected to be overridden in every instance. + match: function() { + throw new Error("unimplemented"); + }, + toString: function() { + throw new Error("unimplemented"); + }, + // This returns a standalone function to do the matching. + func: function() { + return this.match.bind(this); + }, + // Basic combinators + then: function(m) { + return Matcher.seq(this, m); + }, + or: function(m) { + return Matcher.alt(this, m); + }, + andand: function(m) { + return Matcher.many(true, this, m); + }, + oror: function(m) { + return Matcher.many(false, this, m); + }, + // Component value multipliers + star: function() { + return this.braces(0, Infinity, "*"); + }, + plus: function() { + return this.braces(1, Infinity, "+"); + }, + question: function() { + return this.braces(0, 1, "?"); + }, + hash: function() { + return this.braces(1, Infinity, "#", Matcher.cast(",")); + }, + braces: function(min, max, marker, optSep) { + var m1 = this, m2 = optSep ? optSep.then(this) : this; + if (!marker) { + marker = "{" + min + "," + max + "}"; } + return new Matcher(function(expression) { + var result = true, i; + for (i = 0; i < max; i++) { + if (i > 0 && optSep) { + result = m2.match(expression); + } else { + result = m1.match(expression); + } + if (!result) { + break; + } + } + return i >= min; + }, function() { + return m1.toString(Matcher.prec.MOD) + marker; + }); } }; + +},{"../util/StringReader":24,"../util/SyntaxError":25,"./ValidationTypes":21}],4:[function(require,module,exports){ +"use strict"; + +module.exports = MediaFeature; + +var SyntaxUnit = require("../util/SyntaxUnit"); + +var Parser = require("./Parser"); + /** - * Convenient way to read through strings. - * @namespace parserlib.util - * @class StringReader + * Represents a media feature, such as max-width:500. + * @namespace parserlib.css + * @class MediaFeature + * @extends parserlib.util.SyntaxUnit * @constructor - * @param {String} text The text to read. + * @param {SyntaxUnit} name The name of the feature. + * @param {SyntaxUnit} value The value of the feature or null if none. */ -function StringReader(text){ +function MediaFeature(name, value) { + + SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE); /** - * The input text with line endings normalized. - * @property _input + * The name of the media feature * @type String - * @private + * @property name */ - this._input = text.replace(/\n\r?/g, "\n"); - + this.name = name; /** - * The row for the character to be read next. - * @property _line - * @type int - * @private + * The value for the feature or null if there is none. + * @type SyntaxUnit + * @property value */ - this._line = 1; + this.value = value; +} +MediaFeature.prototype = new SyntaxUnit(); +MediaFeature.prototype.constructor = MediaFeature; - /** - * The column for the character to be read next. - * @property _col - * @type int - * @private - */ - this._col = 1; - /** - * The index of the character in the input to be read next. - * @property _cursor - * @type int - * @private - */ - this._cursor = 0; -} +},{"../util/SyntaxUnit":26,"./Parser":6}],5:[function(require,module,exports){ +"use strict"; -StringReader.prototype = { +module.exports = MediaQuery; - //restore constructor - constructor: StringReader, +var SyntaxUnit = require("../util/SyntaxUnit"); - //------------------------------------------------------------------------- - // Position info - //------------------------------------------------------------------------- +var Parser = require("./Parser"); - /** - * Returns the column of the character to be read next. - * @return {int} The column of the character to be read next. - * @method getCol - */ - getCol: function(){ - return this._col; - }, +/** + * Represents an individual media query. + * @namespace parserlib.css + * @class MediaQuery + * @extends parserlib.util.SyntaxUnit + * @constructor + * @param {String} modifier The modifier "not" or "only" (or null). + * @param {String} mediaType The type of media (i.e., "print"). + * @param {Array} parts Array of selectors parts making up this selector. + * @param {int} line The line of text on which the unit resides. + * @param {int} col The column of text on which the unit resides. + */ +function MediaQuery(modifier, mediaType, features, line, col) { + + SyntaxUnit.call(this, (modifier ? modifier + " " : "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); /** - * Returns the row of the character to be read next. - * @return {int} The row of the character to be read next. - * @method getLine + * The media modifier ("not" or "only") + * @type String + * @property modifier */ - getLine: function(){ - return this._line ; - }, + this.modifier = modifier; /** - * Determines if you're at the end of the input. - * @return {Boolean} True if there's no more input, false otherwise. - * @method eof + * The mediaType (i.e., "print") + * @type String + * @property mediaType */ - eof: function(){ - return (this._cursor == this._input.length); - }, - - //------------------------------------------------------------------------- - // Basic reading - //------------------------------------------------------------------------- + this.mediaType = mediaType; /** - * Reads the next character without advancing the cursor. - * @param {int} count How many characters to look ahead (default is 1). - * @return {String} The next character or null if there is no next character. - * @method peek + * The parts that make up the selector. + * @type Array + * @property features */ - peek: function(count){ - var c = null; - count = (typeof count == "undefined" ? 1 : count); + this.features = features; - //if we're not at the end of the input... - if (this._cursor < this._input.length){ +} - //get character and increment cursor and column - c = this._input.charAt(this._cursor + count - 1); - } +MediaQuery.prototype = new SyntaxUnit(); +MediaQuery.prototype.constructor = MediaQuery; - return c; - }, - /** - * Reads the next character from the input and adjusts the row and column - * accordingly. - * @return {String} The next character or null if there is no next character. - * @method read - */ - read: function(){ - var c = null; +},{"../util/SyntaxUnit":26,"./Parser":6}],6:[function(require,module,exports){ +"use strict"; - //if we're not at the end of the input... - if (this._cursor < this._input.length){ +module.exports = Parser; - //if the last character was a newline, increment row count - //and reset column count - if (this._input.charAt(this._cursor) == "\n"){ - this._line++; - this._col=1; - } else { - this._col++; - } +var EventTarget = require("../util/EventTarget"); +var SyntaxError = require("../util/SyntaxError"); +var SyntaxUnit = require("../util/SyntaxUnit"); - //get character and increment cursor and column - c = this._input.charAt(this._cursor++); - } +var Combinator = require("./Combinator"); +var MediaFeature = require("./MediaFeature"); +var MediaQuery = require("./MediaQuery"); +var PropertyName = require("./PropertyName"); +var PropertyValue = require("./PropertyValue"); +var PropertyValuePart = require("./PropertyValuePart"); +var Selector = require("./Selector"); +var SelectorPart = require("./SelectorPart"); +var SelectorSubPart = require("./SelectorSubPart"); +var TokenStream = require("./TokenStream"); +var Tokens = require("./Tokens"); +var Validation = require("./Validation"); - return c; - }, +/** + * A CSS3 parser. + * @namespace parserlib.css + * @class Parser + * @constructor + * @param {Object} options (Optional) Various options for the parser: + * starHack (true|false) to allow IE6 star hack as valid, + * underscoreHack (true|false) to interpret leading underscores + * as IE6-7 targeting for known properties, ieFilters (true|false) + * to indicate that IE < 8 filters should be accepted and not throw + * syntax errors. + */ +function Parser(options) { - //------------------------------------------------------------------------- - // Misc - //------------------------------------------------------------------------- + // inherit event functionality + EventTarget.call(this); - /** - * Saves the current location so it can be returned to later. - * @method mark - * @return {void} - */ - mark: function(){ - this._bookmark = { - cursor: this._cursor, - line: this._line, - col: this._col - }; - }, - reset: function(){ - if (this._bookmark){ - this._cursor = this._bookmark.cursor; - this._line = this._bookmark.line; - this._col = this._bookmark.col; - delete this._bookmark; - } - }, + this.options = options || {}; - //------------------------------------------------------------------------- - // Advanced reading - //------------------------------------------------------------------------- + this._tokenStream = null; +} - /** - * Reads up to and including the given string. Throws an error if that - * string is not found. - * @param {String} pattern The string to read. - * @return {String} The string when it is found. - * @throws Error when the string pattern is not found. - * @method readTo - */ - readTo: function(pattern){ +// Static constants +Parser.DEFAULT_TYPE = 0; +Parser.COMBINATOR_TYPE = 1; +Parser.MEDIA_FEATURE_TYPE = 2; +Parser.MEDIA_QUERY_TYPE = 3; +Parser.PROPERTY_NAME_TYPE = 4; +Parser.PROPERTY_VALUE_TYPE = 5; +Parser.PROPERTY_VALUE_PART_TYPE = 6; +Parser.SELECTOR_TYPE = 7; +Parser.SELECTOR_PART_TYPE = 8; +Parser.SELECTOR_SUB_PART_TYPE = 9; - var buffer = "", - c; +Parser.prototype = function() { - /* - * First, buffer must be the same length as the pattern. - * Then, buffer must end with the pattern or else reach the - * end of the input. - */ - while (buffer.length < pattern.length || buffer.lastIndexOf(pattern) != buffer.length - pattern.length){ - c = this.read(); - if (c){ - buffer += c; - } else { - throw new Error("Expected \"" + pattern + "\" at line " + this._line + ", col " + this._col + "."); - } - } + var proto = new EventTarget(), // new prototype + prop, + additions = { + __proto__: null, - return buffer; + // restore constructor + constructor: Parser, - }, + // instance constants - yuck + DEFAULT_TYPE : 0, + COMBINATOR_TYPE : 1, + MEDIA_FEATURE_TYPE : 2, + MEDIA_QUERY_TYPE : 3, + PROPERTY_NAME_TYPE : 4, + PROPERTY_VALUE_TYPE : 5, + PROPERTY_VALUE_PART_TYPE : 6, + SELECTOR_TYPE : 7, + SELECTOR_PART_TYPE : 8, + SELECTOR_SUB_PART_TYPE : 9, - /** - * Reads characters while each character causes the given - * filter function to return true. The function is passed - * in each character and either returns true to continue - * reading or false to stop. - * @param {Function} filter The function to read on each character. - * @return {String} The string made up of all characters that passed the - * filter check. - * @method readWhile - */ - readWhile: function(filter){ + //----------------------------------------------------------------- + // Grammar + //----------------------------------------------------------------- - var buffer = "", - c = this.read(); + _stylesheet: function() { - while(c !== null && filter(c)){ - buffer += c; - c = this.read(); - } + /* + * stylesheet + * : [ CHARSET_SYM S* STRING S* ';' ]? + * [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* + * [ namespace [S|CDO|CDC]* ]* + * [ [ ruleset | media | page | font_face | keyframes_rule | supports_rule ] [S|CDO|CDC]* ]* + * ; + */ - return buffer; + var tokenStream = this._tokenStream, + count, + token, + tt; - }, + this.fire("startstylesheet"); - /** - * Reads characters that match either text or a regular expression and - * returns those characters. If a match is found, the row and column - * are adjusted; if no match is found, the reader's state is unchanged. - * reading or false to stop. - * @param {String|RegExp} matcher If a string, then the literal string - * value is searched for. If a regular expression, then any string - * matching the pattern is search for. - * @return {String} The string made up of all characters that matched or - * null if there was no match. - * @method readMatch - */ - readMatch: function(matcher){ + // try to read character set + this._charset(); - var source = this._input.substring(this._cursor), - value = null; + this._skipCruft(); - //if it's a string, just do a straight match - if (typeof matcher == "string"){ - if (source.indexOf(matcher) === 0){ - value = this.readCount(matcher.length); - } - } else if (matcher instanceof RegExp){ - if (matcher.test(source)){ - value = this.readCount(RegExp.lastMatch.length); - } - } + // try to read imports - may be more than one + while (tokenStream.peek() === Tokens.IMPORT_SYM) { + this._import(); + this._skipCruft(); + } - return value; - }, + // try to read namespaces - may be more than one + while (tokenStream.peek() === Tokens.NAMESPACE_SYM) { + this._namespace(); + this._skipCruft(); + } + // get the next token + tt = tokenStream.peek(); - /** - * Reads a given number of characters. If the end of the input is reached, - * it reads only the remaining characters and does not throw an error. - * @param {int} count The number of characters to read. - * @return {String} The string made up the read characters. - * @method readCount - */ - readCount: function(count){ - var buffer = ""; + // try to read the rest + while (tt > Tokens.EOF) { - while(count--){ - buffer += this.read(); - } + try { - return buffer; - } + switch (tt) { + case Tokens.MEDIA_SYM: + this._media(); + this._skipCruft(); + break; + case Tokens.PAGE_SYM: + this._page(); + this._skipCruft(); + break; + case Tokens.FONT_FACE_SYM: + this._font_face(); + this._skipCruft(); + break; + case Tokens.KEYFRAMES_SYM: + this._keyframes(); + this._skipCruft(); + break; + case Tokens.VIEWPORT_SYM: + this._viewport(); + this._skipCruft(); + break; + case Tokens.DOCUMENT_SYM: + this._document(); + this._skipCruft(); + break; + case Tokens.SUPPORTS_SYM: + this._supports(); + this._skipCruft(); + break; + case Tokens.UNKNOWN_SYM: // unknown @ rule + tokenStream.get(); + if (!this.options.strict) { -}; -/** - * Type to use when a syntax error occurs. - * @class SyntaxError - * @namespace parserlib.util - * @constructor - * @param {String} message The error message. - * @param {int} line The line at which the error occurred. - * @param {int} col The column at which the error occurred. - */ -function SyntaxError(message, line, col){ + // fire error event + this.fire({ + type: "error", + error: null, + message: "Unknown @ rule: " + tokenStream.LT(0).value + ".", + line: tokenStream.LT(0).startLine, + col: tokenStream.LT(0).startCol + }); - /** - * The column at which the error occurred. - * @type int - * @property col - */ - this.col = col; + // skip braces + count = 0; + while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) === Tokens.LBRACE) { + count++; // keep track of nesting depth + } - /** - * The line at which the error occurred. - * @type int - * @property line - */ - this.line = line; + while (count) { + tokenStream.advance([Tokens.RBRACE]); + count--; + } - /** - * The text representation of the unit. - * @type String - * @property text - */ - this.message = message; + } else { + // not a syntax error, rethrow it + throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol); + } + break; + case Tokens.S: + this._readWhitespace(); + break; + default: + if (!this._ruleset()) { -} + // error handling for known issues + switch (tt) { + case Tokens.CHARSET_SYM: + token = tokenStream.LT(1); + this._charset(false); + throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol); + case Tokens.IMPORT_SYM: + token = tokenStream.LT(1); + this._import(false); + throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol); + case Tokens.NAMESPACE_SYM: + token = tokenStream.LT(1); + this._namespace(false); + throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol); + default: + tokenStream.get(); // get the last token + this._unexpectedToken(tokenStream.token()); + } -//inherit from Error -SyntaxError.prototype = new Error(); -/** - * Base type to represent a single syntactic unit. - * @class SyntaxUnit - * @namespace parserlib.util - * @constructor - * @param {String} text The text of the unit. - * @param {int} line The line of text on which the unit resides. - * @param {int} col The column of text on which the unit resides. - */ -function SyntaxUnit(text, line, col, type){ + } + } + } catch (ex) { + if (ex instanceof SyntaxError && !this.options.strict) { + this.fire({ + type: "error", + error: ex, + message: ex.message, + line: ex.line, + col: ex.col + }); + } else { + throw ex; + } + } + tt = tokenStream.peek(); + } - /** - * The column of text on which the unit resides. - * @type int - * @property col - */ - this.col = col; + if (tt !== Tokens.EOF) { + this._unexpectedToken(tokenStream.token()); + } - /** - * The line of text on which the unit resides. - * @type int - * @property line - */ - this.line = line; + this.fire("endstylesheet"); + }, - /** - * The text representation of the unit. - * @type String - * @property text - */ - this.text = text; + _charset: function(emit) { + var tokenStream = this._tokenStream, + charset, + token, + line, + col; - /** - * The type of syntax unit. - * @type int - * @property type - */ - this.type = type; -} + if (tokenStream.match(Tokens.CHARSET_SYM)) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; -/** - * Create a new syntax unit based solely on the given token. - * Convenience method for creating a new syntax unit when - * it represents a single token instead of multiple. - * @param {Object} token The token object to represent. - * @return {parserlib.util.SyntaxUnit} The object representing the token. - * @static - * @method fromToken - */ -SyntaxUnit.fromToken = function(token){ - return new SyntaxUnit(token.value, token.startLine, token.startCol); -}; + this._readWhitespace(); + tokenStream.mustMatch(Tokens.STRING); -SyntaxUnit.prototype = { + token = tokenStream.token(); + charset = token.value; - //restore constructor - constructor: SyntaxUnit, + this._readWhitespace(); + tokenStream.mustMatch(Tokens.SEMICOLON); - /** - * Returns the text representation of the unit. - * @return {String} The text representation of the unit. - * @method valueOf - */ - valueOf: function(){ - return this.text; - }, + if (emit !== false) { + this.fire({ + type: "charset", + charset:charset, + line: line, + col: col + }); + } + } + }, - /** - * Returns the text representation of the unit. - * @return {String} The text representation of the unit. - * @method toString - */ - toString: function(){ - return this.text; - } + _import: function(emit) { + /* + * import + * : IMPORT_SYM S* + * [STRING|URI] S* media_query_list? ';' S* + */ -}; -/*global StringReader, SyntaxError*/ + var tokenStream = this._tokenStream, + uri, + importToken, + mediaList = []; -/** - * Generic TokenStream providing base functionality. - * @class TokenStreamBase - * @namespace parserlib.util - * @constructor - * @param {String|StringReader} input The text to tokenize or a reader from - * which to read the input. - */ -function TokenStreamBase(input, tokenData){ + // read import symbol + tokenStream.mustMatch(Tokens.IMPORT_SYM); + importToken = tokenStream.token(); + this._readWhitespace(); - /** - * The string reader for easy access to the text. - * @type StringReader - * @property _reader - * @private - */ - this._reader = input ? new StringReader(input.toString()) : null; + tokenStream.mustMatch([Tokens.STRING, Tokens.URI]); - /** - * Token object for the last consumed token. - * @type Token - * @property _token - * @private - */ - this._token = null; + // grab the URI value + uri = tokenStream.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/, "$1"); - /** - * The array of token information. - * @type Array - * @property _tokenData - * @private - */ - this._tokenData = tokenData; + this._readWhitespace(); - /** - * Lookahead token buffer. - * @type Array - * @property _lt - * @private - */ - this._lt = []; + mediaList = this._media_query_list(); - /** - * Lookahead token buffer index. - * @type int - * @property _ltIndex - * @private - */ - this._ltIndex = 0; + // must end with a semicolon + tokenStream.mustMatch(Tokens.SEMICOLON); + this._readWhitespace(); - this._ltIndexCache = []; -} + if (emit !== false) { + this.fire({ + type: "import", + uri: uri, + media: mediaList, + line: importToken.startLine, + col: importToken.startCol + }); + } -/** - * Accepts an array of token information and outputs - * an array of token data containing key-value mappings - * and matching functions that the TokenStream needs. - * @param {Array} tokens An array of token descriptors. - * @return {Array} An array of processed token data. - * @method createTokenData - * @static - */ -TokenStreamBase.createTokenData = function(tokens){ + }, - var nameMap = [], - typeMap = {}, - tokenData = tokens.concat([]), - i = 0, - len = tokenData.length+1; + _namespace: function(emit) { + /* + * namespace + * : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S* + */ - tokenData.UNKNOWN = -1; - tokenData.unshift({name:"EOF"}); + var tokenStream = this._tokenStream, + line, + col, + prefix, + uri; - for (; i < len; i++){ - nameMap.push(tokenData[i].name); - tokenData[tokenData[i].name] = i; - if (tokenData[i].text){ - typeMap[tokenData[i].text] = i; - } - } + // read import symbol + tokenStream.mustMatch(Tokens.NAMESPACE_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + this._readWhitespace(); - tokenData.name = function(tt){ - return nameMap[tt]; - }; + // it's a namespace prefix - no _namespace_prefix() method because it's just an IDENT + if (tokenStream.match(Tokens.IDENT)) { + prefix = tokenStream.token().value; + this._readWhitespace(); + } - tokenData.type = function(c){ - return typeMap[c]; - }; + tokenStream.mustMatch([Tokens.STRING, Tokens.URI]); + /*if (!tokenStream.match(Tokens.STRING)){ + tokenStream.mustMatch(Tokens.URI); + }*/ - return tokenData; -}; + // grab the URI value + uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1"); -TokenStreamBase.prototype = { + this._readWhitespace(); - //restore constructor - constructor: TokenStreamBase, + // must end with a semicolon + tokenStream.mustMatch(Tokens.SEMICOLON); + this._readWhitespace(); - //------------------------------------------------------------------------- - // Matching methods - //------------------------------------------------------------------------- + if (emit !== false) { + this.fire({ + type: "namespace", + prefix: prefix, + uri: uri, + line: line, + col: col + }); + } - /** - * Determines if the next token matches the given token type. - * If so, that token is consumed; if not, the token is placed - * back onto the token stream. You can pass in any number of - * token types and this will return true if any of the token - * types is found. - * @param {int|int[]} tokenTypes Either a single token type or an array of - * token types that the next token might be. If an array is passed, - * it's assumed that the token can be any of these. - * @param {variant} channel (Optional) The channel to read from. If not - * provided, reads from the default (unnamed) channel. - * @return {Boolean} True if the token type matches, false if not. - * @method match - */ - match: function(tokenTypes, channel){ + }, - //always convert to an array, makes things easier - if (!(tokenTypes instanceof Array)){ - tokenTypes = [tokenTypes]; - } + _supports: function(emit) { + /* + * supports_rule + * : SUPPORTS_SYM S* supports_condition S* group_rule_body + * ; + */ + var tokenStream = this._tokenStream, + line, + col; - var tt = this.get(channel), - i = 0, - len = tokenTypes.length; + if (tokenStream.match(Tokens.SUPPORTS_SYM)) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; - while(i < len){ - if (tt == tokenTypes[i++]){ - return true; - } - } + this._readWhitespace(); + this._supports_condition(); + this._readWhitespace(); - //no match found, put the token back - this.unget(); - return false; - }, + tokenStream.mustMatch(Tokens.LBRACE); + this._readWhitespace(); - /** - * Determines if the next token matches the given token type. - * If so, that token is consumed; if not, an error is thrown. - * @param {int|int[]} tokenTypes Either a single token type or an array of - * token types that the next token should be. If an array is passed, - * it's assumed that the token must be one of these. - * @param {variant} channel (Optional) The channel to read from. If not - * provided, reads from the default (unnamed) channel. - * @return {void} - * @method mustMatch - */ - mustMatch: function(tokenTypes, channel){ + if (emit !== false) { + this.fire({ + type: "startsupports", + line: line, + col: col + }); + } - var token; + while (true) { + if (!this._ruleset()) { + break; + } + } - //always convert to an array, makes things easier - if (!(tokenTypes instanceof Array)){ - tokenTypes = [tokenTypes]; - } + tokenStream.mustMatch(Tokens.RBRACE); + this._readWhitespace(); - if (!this.match.apply(this, arguments)){ - token = this.LT(1); - throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name + - " at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); - } - }, + this.fire({ + type: "endsupports", + line: line, + col: col + }); + } + }, - //------------------------------------------------------------------------- - // Consuming methods - //------------------------------------------------------------------------- + _supports_condition: function() { + /* + * supports_condition + * : supports_negation | supports_conjunction | supports_disjunction | + * supports_condition_in_parens + * ; + */ + var tokenStream = this._tokenStream, + ident; - /** - * Keeps reading from the token stream until either one of the specified - * token types is found or until the end of the input is reached. - * @param {int|int[]} tokenTypes Either a single token type or an array of - * token types that the next token should be. If an array is passed, - * it's assumed that the token must be one of these. - * @param {variant} channel (Optional) The channel to read from. If not - * provided, reads from the default (unnamed) channel. - * @return {void} - * @method advance - */ - advance: function(tokenTypes, channel){ + if (tokenStream.match(Tokens.IDENT)) { + ident = tokenStream.token().value.toLowerCase(); - while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){ - this.get(); - } + if (ident === "not") { + tokenStream.mustMatch(Tokens.S); + this._supports_condition_in_parens(); + } else { + tokenStream.unget(); + } + } else { + this._supports_condition_in_parens(); + this._readWhitespace(); - return this.LA(0); - }, + while (tokenStream.peek() === Tokens.IDENT) { + ident = tokenStream.LT(1).value.toLowerCase(); + if (ident === "and" || ident === "or") { + tokenStream.mustMatch(Tokens.IDENT); + this._readWhitespace(); + this._supports_condition_in_parens(); + this._readWhitespace(); + } + } + } + }, - /** - * Consumes the next token from the token stream. - * @return {int} The token type of the token that was just consumed. - * @method get - */ - get: function(channel){ + _supports_condition_in_parens: function() { + /* + * supports_condition_in_parens + * : ( '(' S* supports_condition S* ')' ) | supports_declaration_condition | + * general_enclosed + * ; + */ + var tokenStream = this._tokenStream, + ident; - var tokenInfo = this._tokenData, - reader = this._reader, - value, - i =0, - len = tokenInfo.length, - found = false, - token, - info; + if (tokenStream.match(Tokens.LPAREN)) { + this._readWhitespace(); + if (tokenStream.match(Tokens.IDENT)) { + // look ahead for not keyword, if not given, continue with declaration condition. + ident = tokenStream.token().value.toLowerCase(); + if (ident === "not") { + this._readWhitespace(); + this._supports_condition(); + this._readWhitespace(); + tokenStream.mustMatch(Tokens.RPAREN); + } else { + tokenStream.unget(); + this._supports_declaration_condition(false); + } + } else { + this._supports_condition(); + this._readWhitespace(); + tokenStream.mustMatch(Tokens.RPAREN); + } + } else { + this._supports_declaration_condition(); + } + }, - //check the lookahead buffer first - if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){ + _supports_declaration_condition: function(requireStartParen) { + /* + * supports_declaration_condition + * : '(' S* declaration ')' + * ; + */ + var tokenStream = this._tokenStream; - i++; - this._token = this._lt[this._ltIndex++]; - info = tokenInfo[this._token.type]; + if (requireStartParen !== false) { + tokenStream.mustMatch(Tokens.LPAREN); + } + this._readWhitespace(); + this._declaration(); + tokenStream.mustMatch(Tokens.RPAREN); + }, - //obey channels logic - while((info.channel !== undefined && channel !== info.channel) && - this._ltIndex < this._lt.length){ - this._token = this._lt[this._ltIndex++]; - info = tokenInfo[this._token.type]; - i++; - } + _media: function() { + /* + * media + * : MEDIA_SYM S* media_query_list S* '{' S* ruleset* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col, + mediaList; // = []; - //here be dragons - if ((info.channel === undefined || channel === info.channel) && - this._ltIndex <= this._lt.length){ - this._ltIndexCache.push(i); - return this._token.type; - } - } + // look for @media + tokenStream.mustMatch(Tokens.MEDIA_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; - //call token retriever method - token = this._getToken(); + this._readWhitespace(); - //if it should be hidden, don't save a token - if (token.type > -1 && !tokenInfo[token.type].hide){ + mediaList = this._media_query_list(); - //apply token channel - token.channel = tokenInfo[token.type].channel; + tokenStream.mustMatch(Tokens.LBRACE); + this._readWhitespace(); - //save for later - this._token = token; - this._lt.push(token); + this.fire({ + type: "startmedia", + media: mediaList, + line: line, + col: col + }); - //save space that will be moved (must be done before array is truncated) - this._ltIndexCache.push(this._lt.length - this._ltIndex + i); + while (true) { + if (tokenStream.peek() === Tokens.PAGE_SYM) { + this._page(); + } else if (tokenStream.peek() === Tokens.FONT_FACE_SYM) { + this._font_face(); + } else if (tokenStream.peek() === Tokens.VIEWPORT_SYM) { + this._viewport(); + } else if (tokenStream.peek() === Tokens.DOCUMENT_SYM) { + this._document(); + } else if (tokenStream.peek() === Tokens.SUPPORTS_SYM) { + this._supports(); + } else if (tokenStream.peek() === Tokens.MEDIA_SYM) { + this._media(); + } else if (!this._ruleset()) { + break; + } + } - //keep the buffer under 5 items - if (this._lt.length > 5){ - this._lt.shift(); - } + tokenStream.mustMatch(Tokens.RBRACE); + this._readWhitespace(); - //also keep the shift buffer under 5 items - if (this._ltIndexCache.length > 5){ - this._ltIndexCache.shift(); - } + this.fire({ + type: "endmedia", + media: mediaList, + line: line, + col: col + }); + }, - //update lookahead index - this._ltIndex = this._lt.length; - } - /* - * Skip to the next token if: - * 1. The token type is marked as hidden. - * 2. The token type has a channel specified and it isn't the current channel. - */ - info = tokenInfo[token.type]; - if (info && - (info.hide || - (info.channel !== undefined && channel !== info.channel))){ - return this.get(channel); - } else { - //return just the type - return token.type; - } - }, + // CSS3 Media Queries + _media_query_list: function() { + /* + * media_query_list + * : S* [media_query [ ',' S* media_query ]* ]? + * ; + */ + var tokenStream = this._tokenStream, + mediaList = []; - /** - * Looks ahead a certain number of tokens and returns the token type at - * that position. This will throw an error if you lookahead past the - * end of input, past the size of the lookahead buffer, or back past - * the first token in the lookahead buffer. - * @param {int} The index of the token type to retrieve. 0 for the - * current token, 1 for the next, -1 for the previous, etc. - * @return {int} The token type of the token in the given position. - * @method LA - */ - LA: function(index){ - var total = index, - tt; - if (index > 0){ - //TODO: Store 5 somewhere - if (index > 5){ - throw new Error("Too much lookahead."); - } - //get all those tokens - while(total){ - tt = this.get(); - total--; - } + this._readWhitespace(); - //unget all those tokens - while(total < index){ - this.unget(); - total++; - } - } else if (index < 0){ + if (tokenStream.peek() === Tokens.IDENT || tokenStream.peek() === Tokens.LPAREN) { + mediaList.push(this._media_query()); + } - if(this._lt[this._ltIndex+index]){ - tt = this._lt[this._ltIndex+index].type; - } else { - throw new Error("Too much lookbehind."); - } + while (tokenStream.match(Tokens.COMMA)) { + this._readWhitespace(); + mediaList.push(this._media_query()); + } - } else { - tt = this._token.type; - } - - return tt; + return mediaList; + }, - }, + /* + * Note: "expression" in the grammar maps to the _media_expression + * method. - /** - * Looks ahead a certain number of tokens and returns the token at - * that position. This will throw an error if you lookahead past the - * end of input, past the size of the lookahead buffer, or back past - * the first token in the lookahead buffer. - * @param {int} The index of the token type to retrieve. 0 for the - * current token, 1 for the next, -1 for the previous, etc. - * @return {Object} The token of the token in the given position. - * @method LA - */ - LT: function(index){ + */ + _media_query: function() { + /* + * media_query + * : [ONLY | NOT]? S* media_type S* [ AND S* expression ]* + * | expression [ AND S* expression ]* + * ; + */ + var tokenStream = this._tokenStream, + type = null, + ident = null, + token = null, + expressions = []; - //lookahead first to prime the token buffer - this.LA(index); + if (tokenStream.match(Tokens.IDENT)) { + ident = tokenStream.token().value.toLowerCase(); - //now find the token, subtract one because _ltIndex is already at the next index - return this._lt[this._ltIndex+index-1]; - }, + // since there's no custom tokens for these, need to manually check + if (ident !== "only" && ident !== "not") { + tokenStream.unget(); + ident = null; + } else { + token = tokenStream.token(); + } + } - /** - * Returns the token type for the next token in the stream without - * consuming it. - * @return {int} The token type of the next token in the stream. - * @method peek - */ - peek: function(){ - return this.LA(1); - }, + this._readWhitespace(); - /** - * Returns the actual token object for the last consumed token. - * @return {Token} The token object for the last consumed token. - * @method token - */ - token: function(){ - return this._token; - }, + if (tokenStream.peek() === Tokens.IDENT) { + type = this._media_type(); + if (token === null) { + token = tokenStream.token(); + } + } else if (tokenStream.peek() === Tokens.LPAREN) { + if (token === null) { + token = tokenStream.LT(1); + } + expressions.push(this._media_expression()); + } - /** - * Returns the name of the token for the given token type. - * @param {int} tokenType The type of token to get the name of. - * @return {String} The name of the token or "UNKNOWN_TOKEN" for any - * invalid token type. - * @method tokenName - */ - tokenName: function(tokenType){ - if (tokenType < 0 || tokenType > this._tokenData.length){ - return "UNKNOWN_TOKEN"; - } else { - return this._tokenData[tokenType].name; - } - }, + if (type === null && expressions.length === 0) { + return null; + } else { + this._readWhitespace(); + while (tokenStream.match(Tokens.IDENT)) { + if (tokenStream.token().value.toLowerCase() !== "and") { + this._unexpectedToken(tokenStream.token()); + } - /** - * Returns the token type value for the given token name. - * @param {String} tokenName The name of the token whose value should be returned. - * @return {int} The token type value for the given token name or -1 - * for an unknown token. - * @method tokenName - */ - tokenType: function(tokenName){ - return this._tokenData[tokenName] || -1; - }, + this._readWhitespace(); + expressions.push(this._media_expression()); + } + } - /** - * Returns the last consumed token to the token stream. - * @method unget - */ - unget: function(){ - //if (this._ltIndex > -1){ - if (this._ltIndexCache.length){ - this._ltIndex -= this._ltIndexCache.pop();//--; - this._token = this._lt[this._ltIndex - 1]; - } else { - throw new Error("Too much lookahead."); - } - } + return new MediaQuery(ident, type, expressions, token.startLine, token.startCol); + }, -}; + // CSS3 Media Queries + _media_type: function() { + /* + * media_type + * : IDENT + * ; + */ + return this._media_feature(); + }, + /** + * Note: in CSS3 Media Queries, this is called "expression". + * Renamed here to avoid conflict with CSS3 Selectors + * definition of "expression". Also note that "expr" in the + * grammar now maps to "expression" from CSS3 selectors. + * @method _media_expression + * @private + */ + _media_expression: function() { + /* + * expression + * : '(' S* media_feature S* [ ':' S* expr ]? ')' S* + * ; + */ + var tokenStream = this._tokenStream, + feature = null, + token, + expression = null; -parserlib.util = { -StringReader: StringReader, -SyntaxError : SyntaxError, -SyntaxUnit : SyntaxUnit, -EventTarget : EventTarget, -TokenStreamBase : TokenStreamBase -}; -})(); -/* -Parser-Lib -Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved. + tokenStream.mustMatch(Tokens.LPAREN); + this._readWhitespace(); -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: + feature = this._media_feature(); + this._readWhitespace(); -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. + if (tokenStream.match(Tokens.COLON)) { + this._readWhitespace(); + token = tokenStream.LT(1); + expression = this._expression(); + } -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. + tokenStream.mustMatch(Tokens.RPAREN); + this._readWhitespace(); -*/ -/* Version v0.2.5, Build time: 7-May-2014 03:37:38 */ -(function(){ -var EventTarget = parserlib.util.EventTarget, -TokenStreamBase = parserlib.util.TokenStreamBase, -StringReader = parserlib.util.StringReader, -SyntaxError = parserlib.util.SyntaxError, -SyntaxUnit = parserlib.util.SyntaxUnit; - -var Colors = { - aliceblue :"#f0f8ff", - antiquewhite :"#faebd7", - aqua :"#00ffff", - aquamarine :"#7fffd4", - azure :"#f0ffff", - beige :"#f5f5dc", - bisque :"#ffe4c4", - black :"#000000", - blanchedalmond :"#ffebcd", - blue :"#0000ff", - blueviolet :"#8a2be2", - brown :"#a52a2a", - burlywood :"#deb887", - cadetblue :"#5f9ea0", - chartreuse :"#7fff00", - chocolate :"#d2691e", - coral :"#ff7f50", - cornflowerblue :"#6495ed", - cornsilk :"#fff8dc", - crimson :"#dc143c", - cyan :"#00ffff", - darkblue :"#00008b", - darkcyan :"#008b8b", - darkgoldenrod :"#b8860b", - darkgray :"#a9a9a9", - darkgrey :"#a9a9a9", - darkgreen :"#006400", - darkkhaki :"#bdb76b", - darkmagenta :"#8b008b", - darkolivegreen :"#556b2f", - darkorange :"#ff8c00", - darkorchid :"#9932cc", - darkred :"#8b0000", - darksalmon :"#e9967a", - darkseagreen :"#8fbc8f", - darkslateblue :"#483d8b", - darkslategray :"#2f4f4f", - darkslategrey :"#2f4f4f", - darkturquoise :"#00ced1", - darkviolet :"#9400d3", - deeppink :"#ff1493", - deepskyblue :"#00bfff", - dimgray :"#696969", - dimgrey :"#696969", - dodgerblue :"#1e90ff", - firebrick :"#b22222", - floralwhite :"#fffaf0", - forestgreen :"#228b22", - fuchsia :"#ff00ff", - gainsboro :"#dcdcdc", - ghostwhite :"#f8f8ff", - gold :"#ffd700", - goldenrod :"#daa520", - gray :"#808080", - grey :"#808080", - green :"#008000", - greenyellow :"#adff2f", - honeydew :"#f0fff0", - hotpink :"#ff69b4", - indianred :"#cd5c5c", - indigo :"#4b0082", - ivory :"#fffff0", - khaki :"#f0e68c", - lavender :"#e6e6fa", - lavenderblush :"#fff0f5", - lawngreen :"#7cfc00", - lemonchiffon :"#fffacd", - lightblue :"#add8e6", - lightcoral :"#f08080", - lightcyan :"#e0ffff", - lightgoldenrodyellow :"#fafad2", - lightgray :"#d3d3d3", - lightgrey :"#d3d3d3", - lightgreen :"#90ee90", - lightpink :"#ffb6c1", - lightsalmon :"#ffa07a", - lightseagreen :"#20b2aa", - lightskyblue :"#87cefa", - lightslategray :"#778899", - lightslategrey :"#778899", - lightsteelblue :"#b0c4de", - lightyellow :"#ffffe0", - lime :"#00ff00", - limegreen :"#32cd32", - linen :"#faf0e6", - magenta :"#ff00ff", - maroon :"#800000", - mediumaquamarine:"#66cdaa", - mediumblue :"#0000cd", - mediumorchid :"#ba55d3", - mediumpurple :"#9370d8", - mediumseagreen :"#3cb371", - mediumslateblue :"#7b68ee", - mediumspringgreen :"#00fa9a", - mediumturquoise :"#48d1cc", - mediumvioletred :"#c71585", - midnightblue :"#191970", - mintcream :"#f5fffa", - mistyrose :"#ffe4e1", - moccasin :"#ffe4b5", - navajowhite :"#ffdead", - navy :"#000080", - oldlace :"#fdf5e6", - olive :"#808000", - olivedrab :"#6b8e23", - orange :"#ffa500", - orangered :"#ff4500", - orchid :"#da70d6", - palegoldenrod :"#eee8aa", - palegreen :"#98fb98", - paleturquoise :"#afeeee", - palevioletred :"#d87093", - papayawhip :"#ffefd5", - peachpuff :"#ffdab9", - peru :"#cd853f", - pink :"#ffc0cb", - plum :"#dda0dd", - powderblue :"#b0e0e6", - purple :"#800080", - red :"#ff0000", - rosybrown :"#bc8f8f", - royalblue :"#4169e1", - saddlebrown :"#8b4513", - salmon :"#fa8072", - sandybrown :"#f4a460", - seagreen :"#2e8b57", - seashell :"#fff5ee", - sienna :"#a0522d", - silver :"#c0c0c0", - skyblue :"#87ceeb", - slateblue :"#6a5acd", - slategray :"#708090", - slategrey :"#708090", - snow :"#fffafa", - springgreen :"#00ff7f", - steelblue :"#4682b4", - tan :"#d2b48c", - teal :"#008080", - thistle :"#d8bfd8", - tomato :"#ff6347", - turquoise :"#40e0d0", - violet :"#ee82ee", - wheat :"#f5deb3", - white :"#ffffff", - whitesmoke :"#f5f5f5", - yellow :"#ffff00", - yellowgreen :"#9acd32", - //CSS2 system colors http://www.w3.org/TR/css3-color/#css2-system - activeBorder :"Active window border.", - activecaption :"Active window caption.", - appworkspace :"Background color of multiple document interface.", - background :"Desktop background.", - buttonface :"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.", - buttonhighlight :"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.", - buttonshadow :"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.", - buttontext :"Text on push buttons.", - captiontext :"Text in caption, size box, and scrollbar arrow box.", - graytext :"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.", - greytext :"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.", - highlight :"Item(s) selected in a control.", - highlighttext :"Text of item(s) selected in a control.", - inactiveborder :"Inactive window border.", - inactivecaption :"Inactive window caption.", - inactivecaptiontext :"Color of text in an inactive caption.", - infobackground :"Background color for tooltip controls.", - infotext :"Text color for tooltip controls.", - menu :"Menu background.", - menutext :"Text in menus.", - scrollbar :"Scroll bar gray area.", - threeddarkshadow :"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - threedface :"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - threedhighlight :"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - threedlightshadow :"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - threedshadow :"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - window :"Window background.", - windowframe :"Window frame.", - windowtext :"Text in windows." -}; -/*global SyntaxUnit, Parser*/ -/** - * Represents a selector combinator (whitespace, +, >). - * @namespace parserlib.css - * @class Combinator - * @extends parserlib.util.SyntaxUnit - * @constructor - * @param {String} text The text representation of the unit. - * @param {int} line The line of text on which the unit resides. - * @param {int} col The column of text on which the unit resides. - */ -function Combinator(text, line, col){ + return new MediaFeature(feature, expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null); + }, - SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE); + // CSS3 Media Queries + _media_feature: function() { + /* + * media_feature + * : IDENT + * ; + */ + var tokenStream = this._tokenStream; - /** - * The type of modifier. - * @type String - * @property type - */ - this.type = "unknown"; + this._readWhitespace(); - //pretty simple - if (/^\s+$/.test(text)){ - this.type = "descendant"; - } else if (text == ">"){ - this.type = "child"; - } else if (text == "+"){ - this.type = "adjacent-sibling"; - } else if (text == "~"){ - this.type = "sibling"; - } + tokenStream.mustMatch(Tokens.IDENT); -} + return SyntaxUnit.fromToken(tokenStream.token()); + }, -Combinator.prototype = new SyntaxUnit(); -Combinator.prototype.constructor = Combinator; + // CSS3 Paged Media + _page: function() { + /* + * page: + * PAGE_SYM S* IDENT? pseudo_page? S* + * '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col, + identifier = null, + pseudoPage = null; -/*global SyntaxUnit, Parser*/ -/** - * Represents a media feature, such as max-width:500. - * @namespace parserlib.css - * @class MediaFeature - * @extends parserlib.util.SyntaxUnit - * @constructor - * @param {SyntaxUnit} name The name of the feature. - * @param {SyntaxUnit} value The value of the feature or null if none. - */ -function MediaFeature(name, value){ + // look for @page + tokenStream.mustMatch(Tokens.PAGE_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; - SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE); + this._readWhitespace(); - /** - * The name of the media feature - * @type String - * @property name - */ - this.name = name; + if (tokenStream.match(Tokens.IDENT)) { + identifier = tokenStream.token().value; - /** - * The value for the feature or null if there is none. - * @type SyntaxUnit - * @property value - */ - this.value = value; -} + // The value 'auto' may not be used as a page name and MUST be treated as a syntax error. + if (identifier.toLowerCase() === "auto") { + this._unexpectedToken(tokenStream.token()); + } + } -MediaFeature.prototype = new SyntaxUnit(); -MediaFeature.prototype.constructor = MediaFeature; + // see if there's a colon upcoming + if (tokenStream.peek() === Tokens.COLON) { + pseudoPage = this._pseudo_page(); + } -/*global SyntaxUnit, Parser*/ -/** - * Represents an individual media query. - * @namespace parserlib.css - * @class MediaQuery - * @extends parserlib.util.SyntaxUnit - * @constructor - * @param {String} modifier The modifier "not" or "only" (or null). - * @param {String} mediaType The type of media (i.e., "print"). - * @param {Array} parts Array of selectors parts making up this selector. - * @param {int} line The line of text on which the unit resides. - * @param {int} col The column of text on which the unit resides. - */ -function MediaQuery(modifier, mediaType, features, line, col){ + this._readWhitespace(); - SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); + this.fire({ + type: "startpage", + id: identifier, + pseudo: pseudoPage, + line: line, + col: col + }); - /** - * The media modifier ("not" or "only") - * @type String - * @property modifier - */ - this.modifier = modifier; + this._readDeclarations(true, true); - /** - * The mediaType (i.e., "print") - * @type String - * @property mediaType - */ - this.mediaType = mediaType; + this.fire({ + type: "endpage", + id: identifier, + pseudo: pseudoPage, + line: line, + col: col + }); - /** - * The parts that make up the selector. - * @type Array - * @property features - */ - this.features = features; + }, -} + // CSS3 Paged Media + _margin: function() { + /* + * margin : + * margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col, + marginSym = this._margin_sym(); -MediaQuery.prototype = new SyntaxUnit(); -MediaQuery.prototype.constructor = MediaQuery; + if (marginSym) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; -/*global Tokens, TokenStream, SyntaxError, Properties, Validation, ValidationError, SyntaxUnit, - PropertyValue, PropertyValuePart, SelectorPart, SelectorSubPart, Selector, - PropertyName, Combinator, MediaFeature, MediaQuery, EventTarget */ + this.fire({ + type: "startpagemargin", + margin: marginSym, + line: line, + col: col + }); -/** - * A CSS3 parser. - * @namespace parserlib.css - * @class Parser - * @constructor - * @param {Object} options (Optional) Various options for the parser: - * starHack (true|false) to allow IE6 star hack as valid, - * underscoreHack (true|false) to interpret leading underscores - * as IE6-7 targeting for known properties, ieFilters (true|false) - * to indicate that IE < 8 filters should be accepted and not throw - * syntax errors. - */ -function Parser(options){ + this._readDeclarations(true); - //inherit event functionality - EventTarget.call(this); + this.fire({ + type: "endpagemargin", + margin: marginSym, + line: line, + col: col + }); + return true; + } else { + return false; + } + }, + // CSS3 Paged Media + _margin_sym: function() { - this.options = options || {}; + /* + * margin_sym : + * TOPLEFTCORNER_SYM | + * TOPLEFT_SYM | + * TOPCENTER_SYM | + * TOPRIGHT_SYM | + * TOPRIGHTCORNER_SYM | + * BOTTOMLEFTCORNER_SYM | + * BOTTOMLEFT_SYM | + * BOTTOMCENTER_SYM | + * BOTTOMRIGHT_SYM | + * BOTTOMRIGHTCORNER_SYM | + * LEFTTOP_SYM | + * LEFTMIDDLE_SYM | + * LEFTBOTTOM_SYM | + * RIGHTTOP_SYM | + * RIGHTMIDDLE_SYM | + * RIGHTBOTTOM_SYM + * ; + */ - this._tokenStream = null; -} + var tokenStream = this._tokenStream; -//Static constants -Parser.DEFAULT_TYPE = 0; -Parser.COMBINATOR_TYPE = 1; -Parser.MEDIA_FEATURE_TYPE = 2; -Parser.MEDIA_QUERY_TYPE = 3; -Parser.PROPERTY_NAME_TYPE = 4; -Parser.PROPERTY_VALUE_TYPE = 5; -Parser.PROPERTY_VALUE_PART_TYPE = 6; -Parser.SELECTOR_TYPE = 7; -Parser.SELECTOR_PART_TYPE = 8; -Parser.SELECTOR_SUB_PART_TYPE = 9; + if (tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM, + Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM, + Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM, + Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM, + Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM, + Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM, + Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) { + return SyntaxUnit.fromToken(tokenStream.token()); + } else { + return null; + } -Parser.prototype = function(){ + }, - var proto = new EventTarget(), //new prototype - prop, - additions = { + _pseudo_page: function() { + /* + * pseudo_page + * : ':' IDENT + * ; + */ - //restore constructor - constructor: Parser, + var tokenStream = this._tokenStream; - //instance constants - yuck - DEFAULT_TYPE : 0, - COMBINATOR_TYPE : 1, - MEDIA_FEATURE_TYPE : 2, - MEDIA_QUERY_TYPE : 3, - PROPERTY_NAME_TYPE : 4, - PROPERTY_VALUE_TYPE : 5, - PROPERTY_VALUE_PART_TYPE : 6, - SELECTOR_TYPE : 7, - SELECTOR_PART_TYPE : 8, - SELECTOR_SUB_PART_TYPE : 9, + tokenStream.mustMatch(Tokens.COLON); + tokenStream.mustMatch(Tokens.IDENT); - //----------------------------------------------------------------- - // Grammar - //----------------------------------------------------------------- + // TODO: CSS3 Paged Media says only "left", "center", and "right" are allowed - _stylesheet: function(){ + return tokenStream.token().value; + }, + _font_face: function() { /* - * stylesheet - * : [ CHARSET_SYM S* STRING S* ';' ]? - * [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* - * [ namespace [S|CDO|CDC]* ]* - * [ [ ruleset | media | page | font_face | keyframes ] [S|CDO|CDC]* ]* - * ; + * font_face + * : FONT_FACE_SYM S* + * '{' S* declaration [ ';' S* declaration ]* '}' S* + * ; */ - var tokenStream = this._tokenStream, - charset = null, - count, - token, - tt; + line, + col; - this.fire("startstylesheet"); + // look for @page + tokenStream.mustMatch(Tokens.FONT_FACE_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; - //try to read character set - this._charset(); + this._readWhitespace(); - this._skipCruft(); + this.fire({ + type: "startfontface", + line: line, + col: col + }); - //try to read imports - may be more than one - while (tokenStream.peek() == Tokens.IMPORT_SYM){ - this._import(); - this._skipCruft(); - } + this._readDeclarations(true); - //try to read namespaces - may be more than one - while (tokenStream.peek() == Tokens.NAMESPACE_SYM){ - this._namespace(); - this._skipCruft(); - } + this.fire({ + type: "endfontface", + line: line, + col: col + }); + }, - //get the next token - tt = tokenStream.peek(); + _viewport: function() { + /* + * viewport + * : VIEWPORT_SYM S* + * '{' S* declaration? [ ';' S* declaration? ]* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col; - //try to read the rest - while(tt > Tokens.EOF){ + tokenStream.mustMatch(Tokens.VIEWPORT_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; - try { + this._readWhitespace(); - switch(tt){ - case Tokens.MEDIA_SYM: - this._media(); - this._skipCruft(); - break; - case Tokens.PAGE_SYM: - this._page(); - this._skipCruft(); - break; - case Tokens.FONT_FACE_SYM: - this._font_face(); - this._skipCruft(); - break; - case Tokens.KEYFRAMES_SYM: - this._keyframes(); - this._skipCruft(); - break; - case Tokens.VIEWPORT_SYM: - this._viewport(); - this._skipCruft(); - break; - case Tokens.UNKNOWN_SYM: //unknown @ rule - tokenStream.get(); - if (!this.options.strict){ + this.fire({ + type: "startviewport", + line: line, + col: col + }); - //fire error event - this.fire({ - type: "error", - error: null, - message: "Unknown @ rule: " + tokenStream.LT(0).value + ".", - line: tokenStream.LT(0).startLine, - col: tokenStream.LT(0).startCol - }); + this._readDeclarations(true); - //skip braces - count=0; - while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){ - count++; //keep track of nesting depth - } + this.fire({ + type: "endviewport", + line: line, + col: col + }); - while(count){ - tokenStream.advance([Tokens.RBRACE]); - count--; - } + }, - } else { - //not a syntax error, rethrow it - throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol); - } - break; - case Tokens.S: - this._readWhitespace(); - break; - default: - if(!this._ruleset()){ + _document: function() { + /* + * document + * : DOCUMENT_SYM S* + * _document_function [ ',' S* _document_function ]* S* + * '{' S* ruleset* '}' + * ; + */ - //error handling for known issues - switch(tt){ - case Tokens.CHARSET_SYM: - token = tokenStream.LT(1); - this._charset(false); - throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol); - case Tokens.IMPORT_SYM: - token = tokenStream.LT(1); - this._import(false); - throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol); - case Tokens.NAMESPACE_SYM: - token = tokenStream.LT(1); - this._namespace(false); - throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol); - default: - tokenStream.get(); //get the last token - this._unexpectedToken(tokenStream.token()); - } - - } - } - } catch(ex) { - if (ex instanceof SyntaxError && !this.options.strict){ - this.fire({ - type: "error", - error: ex, - message: ex.message, - line: ex.line, - col: ex.col - }); - } else { - throw ex; - } - } - - tt = tokenStream.peek(); - } - - if (tt != Tokens.EOF){ - this._unexpectedToken(tokenStream.token()); - } - - this.fire("endstylesheet"); - }, - - _charset: function(emit){ var tokenStream = this._tokenStream, - charset, token, - line, - col; + functions = [], + prefix = ""; - if (tokenStream.match(Tokens.CHARSET_SYM)){ - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; + tokenStream.mustMatch(Tokens.DOCUMENT_SYM); + token = tokenStream.token(); + if (/^@-([^-]+)-/.test(token.value)) { + prefix = RegExp.$1; + } + + this._readWhitespace(); + functions.push(this._document_function()); + while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); - tokenStream.mustMatch(Tokens.STRING); + functions.push(this._document_function()); + } - token = tokenStream.token(); - charset = token.value; + tokenStream.mustMatch(Tokens.LBRACE); + this._readWhitespace(); - this._readWhitespace(); - tokenStream.mustMatch(Tokens.SEMICOLON); + this.fire({ + type: "startdocument", + functions: functions, + prefix: prefix, + line: token.startLine, + col: token.startCol + }); - if (emit !== false){ - this.fire({ - type: "charset", - charset:charset, - line: line, - col: col - }); + var ok = true; + while (ok) { + switch (tokenStream.peek()) { + case Tokens.PAGE_SYM: + this._page(); + break; + case Tokens.FONT_FACE_SYM: + this._font_face(); + break; + case Tokens.VIEWPORT_SYM: + this._viewport(); + break; + case Tokens.MEDIA_SYM: + this._media(); + break; + case Tokens.KEYFRAMES_SYM: + this._keyframes(); + break; + case Tokens.DOCUMENT_SYM: + this._document(); + break; + default: + ok = Boolean(this._ruleset()); } } + + tokenStream.mustMatch(Tokens.RBRACE); + token = tokenStream.token(); + this._readWhitespace(); + + this.fire({ + type: "enddocument", + functions: functions, + prefix: prefix, + line: token.startLine, + col: token.startCol + }); }, - _import: function(emit){ + _document_function: function() { /* - * import - * : IMPORT_SYM S* - * [STRING|URI] S* media_query_list? ';' S* + * document_function + * : function | URI S* + * ; */ var tokenStream = this._tokenStream, - tt, - uri, - importToken, - mediaList = []; - - //read import symbol - tokenStream.mustMatch(Tokens.IMPORT_SYM); - importToken = tokenStream.token(); - this._readWhitespace(); - - tokenStream.mustMatch([Tokens.STRING, Tokens.URI]); - - //grab the URI value - uri = tokenStream.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/, "$1"); - - this._readWhitespace(); - - mediaList = this._media_query_list(); - - //must end with a semicolon - tokenStream.mustMatch(Tokens.SEMICOLON); - this._readWhitespace(); + value; - if (emit !== false){ - this.fire({ - type: "import", - uri: uri, - media: mediaList, - line: importToken.startLine, - col: importToken.startCol - }); + if (tokenStream.match(Tokens.URI)) { + value = tokenStream.token().value; + this._readWhitespace(); + } else { + value = this._function(); } + return value; }, - _namespace: function(emit){ + _operator: function(inFunction) { + /* - * namespace - * : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S* + * operator (outside function) + * : '/' S* | ',' S* | /( empty )/ + * operator (inside function) + * : '/' S* | '+' S* | '*' S* | '-' S* /( empty )/ + * ; */ var tokenStream = this._tokenStream, - line, - col, - prefix, - uri; - - //read import symbol - tokenStream.mustMatch(Tokens.NAMESPACE_SYM); - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; - this._readWhitespace(); + token = null; - //it's a namespace prefix - no _namespace_prefix() method because it's just an IDENT - if (tokenStream.match(Tokens.IDENT)){ - prefix = tokenStream.token().value; + if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) || + inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS])) { + token = tokenStream.token(); this._readWhitespace(); } + return token ? PropertyValuePart.fromToken(token) : null; - tokenStream.mustMatch([Tokens.STRING, Tokens.URI]); - /*if (!tokenStream.match(Tokens.STRING)){ - tokenStream.mustMatch(Tokens.URI); - }*/ + }, - //grab the URI value - uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1"); + _combinator: function() { - this._readWhitespace(); + /* + * combinator + * : PLUS S* | GREATER S* | TILDE S* | S+ + * ; + */ - //must end with a semicolon - tokenStream.mustMatch(Tokens.SEMICOLON); - this._readWhitespace(); + var tokenStream = this._tokenStream, + value = null, + token; - if (emit !== false){ - this.fire({ - type: "namespace", - prefix: prefix, - uri: uri, - line: line, - col: col - }); + if (tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])) { + token = tokenStream.token(); + value = new Combinator(token.value, token.startLine, token.startCol); + this._readWhitespace(); } + return value; }, - _media: function(){ + _unary_operator: function() { + /* - * media - * : MEDIA_SYM S* media_query_list S* '{' S* ruleset* '}' S* - * ; + * unary_operator + * : '-' | '+' + * ; */ - var tokenStream = this._tokenStream, - line, - col, - mediaList;// = []; - - //look for @media - tokenStream.mustMatch(Tokens.MEDIA_SYM); - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; - - this._readWhitespace(); - - mediaList = this._media_query_list(); - tokenStream.mustMatch(Tokens.LBRACE); - this._readWhitespace(); - - this.fire({ - type: "startmedia", - media: mediaList, - line: line, - col: col - }); + var tokenStream = this._tokenStream; - while(true) { - if (tokenStream.peek() == Tokens.PAGE_SYM){ - this._page(); - } else if (tokenStream.peek() == Tokens.FONT_FACE_SYM){ - this._font_face(); - } else if (tokenStream.peek() == Tokens.VIEWPORT_SYM){ - this._viewport(); - } else if (!this._ruleset()){ - break; - } + if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])) { + return tokenStream.token().value; + } else { + return null; } - - tokenStream.mustMatch(Tokens.RBRACE); - this._readWhitespace(); - - this.fire({ - type: "endmedia", - media: mediaList, - line: line, - col: col - }); }, + _property: function() { - //CSS3 Media Queries - _media_query_list: function(){ /* - * media_query_list - * : S* [media_query [ ',' S* media_query ]* ]? + * property + * : IDENT S* * ; */ - var tokenStream = this._tokenStream, - mediaList = []; + var tokenStream = this._tokenStream, + value = null, + hack = null, + propertyName = "", + token, + line, + col; - this._readWhitespace(); + // check for star hack - throws error if not allowed + if (tokenStream.peek() === Tokens.STAR && this.options.starHack) { + tokenStream.get(); + token = tokenStream.token(); + hack = token.value; + line = token.startLine; + col = token.startCol; + } - if (tokenStream.peek() == Tokens.IDENT || tokenStream.peek() == Tokens.LPAREN){ - mediaList.push(this._media_query()); + // consume a single hyphen before finding the identifier, to support custom properties + if (tokenStream.peek() === Tokens.MINUS) { + tokenStream.get(); + token = tokenStream.token(); + propertyName = token.value; + line = token.startLine; + col = token.startCol; } - while(tokenStream.match(Tokens.COMMA)){ + if (tokenStream.match(Tokens.IDENT)) { + token = tokenStream.token(); + propertyName += token.value; + + // check for underscore hack - no error if not allowed because it's valid CSS syntax + if (propertyName.charAt(0) === "_" && this.options.underscoreHack) { + hack = "_"; + propertyName = propertyName.substring(1); + } + + value = new PropertyName(propertyName, hack, line || token.startLine, col || token.startCol); this._readWhitespace(); - mediaList.push(this._media_query()); + } else { + var tt = tokenStream.peek(); + // If this isn't an right brace or the end of the file throw an SyntaxError. + if (tt !== Tokens.EOF && tt !== Tokens.RBRACE) { + this._unexpectedToken(tokenStream.LT(1)); + } } - return mediaList; + return value; }, - /* - * Note: "expression" in the grammar maps to the _media_expression - * method. - - */ - _media_query: function(){ + // Augmented with CSS3 Selectors + _ruleset: function() { /* - * media_query - * : [ONLY | NOT]? S* media_type S* [ AND S* expression ]* - * | expression [ AND S* expression ]* + * ruleset + * : selectors_group + * '{' S* declaration? [ ';' S* declaration? ]* '}' S* * ; */ + var tokenStream = this._tokenStream, - type = null, - ident = null, - token = null, - expressions = []; + tt, + selectors; - if (tokenStream.match(Tokens.IDENT)){ - ident = tokenStream.token().value.toLowerCase(); - //since there's no custom tokens for these, need to manually check - if (ident != "only" && ident != "not"){ - tokenStream.unget(); - ident = null; + /* + * Error Recovery: If even a single selector fails to parse, + * then the entire ruleset should be thrown away. + */ + try { + selectors = this._selectors_group(); + } catch (ex) { + if (ex instanceof SyntaxError && !this.options.strict) { + + // fire error event + this.fire({ + type: "error", + error: ex, + message: ex.message, + line: ex.line, + col: ex.col + }); + + // skip over everything until closing brace + tt = tokenStream.advance([Tokens.RBRACE]); + if (tt === Tokens.RBRACE) { + // if there's a right brace, the rule is finished so don't do anything + } else { + // otherwise, rethrow the error because it wasn't handled properly + throw ex; + } + } else { - token = tokenStream.token(); + // not a syntax error, rethrow it + throw ex; } + + // trigger parser to continue + return true; } - this._readWhitespace(); + // if it got here, all selectors parsed + if (selectors) { - if (tokenStream.peek() == Tokens.IDENT){ - type = this._media_type(); - if (token === null){ - token = tokenStream.token(); - } - } else if (tokenStream.peek() == Tokens.LPAREN){ - if (token === null){ - token = tokenStream.LT(1); - } - expressions.push(this._media_expression()); - } + this.fire({ + type: "startrule", + selectors: selectors, + line: selectors[0].line, + col: selectors[0].col + }); - if (type === null && expressions.length === 0){ - return null; - } else { - this._readWhitespace(); - while (tokenStream.match(Tokens.IDENT)){ - if (tokenStream.token().value.toLowerCase() != "and"){ - this._unexpectedToken(tokenStream.token()); - } + this._readDeclarations(true); + + this.fire({ + type: "endrule", + selectors: selectors, + line: selectors[0].line, + col: selectors[0].col + }); - this._readWhitespace(); - expressions.push(this._media_expression()); - } } - return new MediaQuery(ident, type, expressions, token.startLine, token.startCol); - }, + return selectors; - //CSS3 Media Queries - _media_type: function(){ - /* - * media_type - * : IDENT - * ; - */ - return this._media_feature(); }, - /** - * Note: in CSS3 Media Queries, this is called "expression". - * Renamed here to avoid conflict with CSS3 Selectors - * definition of "expression". Also note that "expr" in the - * grammar now maps to "expression" from CSS3 selectors. - * @method _media_expression - * @private - */ - _media_expression: function(){ + // CSS3 Selectors + _selectors_group: function() { + /* - * expression - * : '(' S* media_feature S* [ ':' S* expr ]? ')' S* - * ; + * selectors_group + * : selector [ COMMA S* selector ]* + * ; */ var tokenStream = this._tokenStream, - feature = null, - token, - expression = null; - - tokenStream.mustMatch(Tokens.LPAREN); - this._readWhitespace(); + selectors = [], + selector; - feature = this._media_feature(); - this._readWhitespace(); + selector = this._selector(); + if (selector !== null) { - if (tokenStream.match(Tokens.COLON)){ - this._readWhitespace(); - token = tokenStream.LT(1); - expression = this._expression(); + selectors.push(selector); + while (tokenStream.match(Tokens.COMMA)) { + this._readWhitespace(); + selector = this._selector(); + if (selector !== null) { + selectors.push(selector); + } else { + this._unexpectedToken(tokenStream.LT(1)); + } + } } - tokenStream.mustMatch(Tokens.RPAREN); - this._readWhitespace(); - - return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null)); + return selectors.length ? selectors : null; }, - //CSS3 Media Queries - _media_feature: function(){ + // CSS3 Selectors + _selector: function() { /* - * media_feature - * : IDENT + * selector + * : simple_selector_sequence [ combinator simple_selector_sequence ]* * ; */ - var tokenStream = this._tokenStream; - tokenStream.mustMatch(Tokens.IDENT); + var tokenStream = this._tokenStream, + selector = [], + nextSelector = null, + combinator = null, + ws = null; - return SyntaxUnit.fromToken(tokenStream.token()); - }, + // if there's no simple selector, then there's no selector + nextSelector = this._simple_selector_sequence(); + if (nextSelector === null) { + return null; + } - //CSS3 Paged Media - _page: function(){ - /* - * page: - * PAGE_SYM S* IDENT? pseudo_page? S* - * '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S* - * ; - */ - var tokenStream = this._tokenStream, - line, - col, - identifier = null, - pseudoPage = null; + selector.push(nextSelector); - //look for @page - tokenStream.mustMatch(Tokens.PAGE_SYM); - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; + do { - this._readWhitespace(); + // look for a combinator + combinator = this._combinator(); - if (tokenStream.match(Tokens.IDENT)){ - identifier = tokenStream.token().value; + if (combinator !== null) { + selector.push(combinator); + nextSelector = this._simple_selector_sequence(); - //The value 'auto' may not be used as a page name and MUST be treated as a syntax error. - if (identifier.toLowerCase() === "auto"){ - this._unexpectedToken(tokenStream.token()); - } - } + // there must be a next selector + if (nextSelector === null) { + this._unexpectedToken(tokenStream.LT(1)); + } else { - //see if there's a colon upcoming - if (tokenStream.peek() == Tokens.COLON){ - pseudoPage = this._pseudo_page(); - } + // nextSelector is an instance of SelectorPart + selector.push(nextSelector); + } + } else { - this._readWhitespace(); + // if there's not whitespace, we're done + if (this._readWhitespace()) { - this.fire({ - type: "startpage", - id: identifier, - pseudo: pseudoPage, - line: line, - col: col - }); + // add whitespace separator + ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol); - this._readDeclarations(true, true); + //combinator is not required + combinator = this._combinator(); - this.fire({ - type: "endpage", - id: identifier, - pseudo: pseudoPage, - line: line, - col: col - }); + // selector is required if there's a combinator + nextSelector = this._simple_selector_sequence(); + if (nextSelector === null) { + if (combinator !== null) { + this._unexpectedToken(tokenStream.LT(1)); + } + } else { + if (combinator !== null) { + selector.push(combinator); + } else { + selector.push(ws); + } + + selector.push(nextSelector); + } + } else { + break; + } + + } + } while (true); + + return new Selector(selector, selector[0].line, selector[0].col); }, - //CSS3 Paged Media - _margin: function(){ + // CSS3 Selectors + _simple_selector_sequence: function() { /* - * margin : - * margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S* - * ; + * simple_selector_sequence + * : [ type_selector | universal ] + * [ HASH | class | attrib | pseudo | negation ]* + * | [ HASH | class | attrib | pseudo | negation ]+ + * ; */ + var tokenStream = this._tokenStream, + + // parts of a simple selector + elementName = null, + modifiers = [], + + // complete selector text + selectorText = "", + + // the different parts after the element name to search for + components = [ + // HASH + function() { + return tokenStream.match(Tokens.HASH) ? + new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : + null; + }, + this._class, + this._attrib, + this._pseudo, + this._negation + ], + i = 0, + len = components.length, + component = null, line, - col, - marginSym = this._margin_sym(); + col; - if (marginSym){ - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; - this.fire({ - type: "startpagemargin", - margin: marginSym, - line: line, - col: col - }); + // get starting line and column for the selector + line = tokenStream.LT(1).startLine; + col = tokenStream.LT(1).startCol; - this._readDeclarations(true); + elementName = this._type_selector(); + if (!elementName) { + elementName = this._universal(); + } - this.fire({ - type: "endpagemargin", - margin: marginSym, - line: line, - col: col - }); - return true; - } else { - return false; + if (elementName !== null) { + selectorText += elementName; } - }, - //CSS3 Paged Media - _margin_sym: function(){ + while (true) { - /* - * margin_sym : - * TOPLEFTCORNER_SYM | - * TOPLEFT_SYM | - * TOPCENTER_SYM | - * TOPRIGHT_SYM | - * TOPRIGHTCORNER_SYM | - * BOTTOMLEFTCORNER_SYM | - * BOTTOMLEFT_SYM | - * BOTTOMCENTER_SYM | - * BOTTOMRIGHT_SYM | - * BOTTOMRIGHTCORNER_SYM | - * LEFTTOP_SYM | - * LEFTMIDDLE_SYM | - * LEFTBOTTOM_SYM | - * RIGHTTOP_SYM | - * RIGHTMIDDLE_SYM | - * RIGHTBOTTOM_SYM - * ; - */ + // whitespace means we're done + if (tokenStream.peek() === Tokens.S) { + break; + } - var tokenStream = this._tokenStream; + // check for each component + while (i < len && component === null) { + component = components[i++].call(this); + } - if(tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM, - Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM, - Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM, - Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM, - Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM, - Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM, - Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) - { - return SyntaxUnit.fromToken(tokenStream.token()); - } else { - return null; + if (component === null) { + + // we don't have a selector + if (selectorText === "") { + return null; + } else { + break; + } + } else { + i = 0; + modifiers.push(component); + selectorText += component.toString(); + component = null; + } } + + return selectorText !== "" ? + new SelectorPart(elementName, modifiers, selectorText, line, col) : + null; }, - _pseudo_page: function(){ + // CSS3 Selectors + _type_selector: function() { /* - * pseudo_page - * : ':' IDENT + * type_selector + * : [ namespace_prefix ]? element_name * ; */ - var tokenStream = this._tokenStream; - - tokenStream.mustMatch(Tokens.COLON); - tokenStream.mustMatch(Tokens.IDENT); + var tokenStream = this._tokenStream, + ns = this._namespace_prefix(), + elementName = this._element_name(); - //TODO: CSS3 Paged Media says only "left", "center", and "right" are allowed + if (!elementName) { + /* + * Need to back out the namespace that was read due to both + * type_selector and universal reading namespace_prefix + * first. Kind of hacky, but only way I can figure out + * right now how to not change the grammar. + */ + if (ns) { + tokenStream.unget(); + if (ns.length > 1) { + tokenStream.unget(); + } + } - return tokenStream.token().value; + return null; + } else { + if (ns) { + elementName.text = ns + elementName.text; + elementName.col -= ns.length; + } + return elementName; + } }, - _font_face: function(){ + // CSS3 Selectors + _class: function() { /* - * font_face - * : FONT_FACE_SYM S* - * '{' S* declaration [ ';' S* declaration ]* '}' S* + * class + * : '.' IDENT * ; */ + var tokenStream = this._tokenStream, - line, - col; + token; - //look for @page - tokenStream.mustMatch(Tokens.FONT_FACE_SYM); - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; + if (tokenStream.match(Tokens.DOT)) { + tokenStream.mustMatch(Tokens.IDENT); + token = tokenStream.token(); + return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1); + } else { + return null; + } - this._readWhitespace(); + }, - this.fire({ - type: "startfontface", - line: line, - col: col - }); + // CSS3 Selectors + _element_name: function() { + /* + * element_name + * : IDENT + * ; + */ - this._readDeclarations(true); + var tokenStream = this._tokenStream, + token; - this.fire({ - type: "endfontface", - line: line, - col: col - }); + if (tokenStream.match(Tokens.IDENT)) { + token = tokenStream.token(); + return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol); + + } else { + return null; + } }, - _viewport: function(){ + // CSS3 Selectors + _namespace_prefix: function() { /* - * viewport - * : VIEWPORT_SYM S* - * '{' S* declaration? [ ';' S* declaration? ]* '}' S* + * namespace_prefix + * : [ IDENT | '*' ]? '|' * ; */ - var tokenStream = this._tokenStream, - line, - col; - - tokenStream.mustMatch(Tokens.VIEWPORT_SYM); - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; + var tokenStream = this._tokenStream, + value = ""; - this._readWhitespace(); + // verify that this is a namespace prefix + if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE) { - this.fire({ - type: "startviewport", - line: line, - col: col - }); + if (tokenStream.match([Tokens.IDENT, Tokens.STAR])) { + value += tokenStream.token().value; + } - this._readDeclarations(true); + tokenStream.mustMatch(Tokens.PIPE); + value += "|"; - this.fire({ - type: "endviewport", - line: line, - col: col - }); + } + return value.length ? value : null; }, - _operator: function(inFunction){ - + // CSS3 Selectors + _universal: function() { /* - * operator (outside function) - * : '/' S* | ',' S* | /( empty )/ - * operator (inside function) - * : '/' S* | '+' S* | '*' S* | '-' S* /( empty )/ - * ; + * universal + * : [ namespace_prefix ]? '*' + * ; */ - var tokenStream = this._tokenStream, - token = null; + value = "", + ns; - if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) || - (inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))){ - token = tokenStream.token(); - this._readWhitespace(); + ns = this._namespace_prefix(); + if (ns) { + value += ns; } - return token ? PropertyValuePart.fromToken(token) : null; - }, + if (tokenStream.match(Tokens.STAR)) { + value += "*"; + } + + return value.length ? value : null; - _combinator: function(){ + }, + // CSS3 Selectors + _attrib: function() { /* - * combinator - * : PLUS S* | GREATER S* | TILDE S* | S+ - * ; + * attrib + * : '[' S* [ namespace_prefix ]? IDENT S* + * [ [ PREFIXMATCH | + * SUFFIXMATCH | + * SUBSTRINGMATCH | + * '=' | + * INCLUDES | + * DASHMATCH ] S* [ IDENT | STRING ] S* + * ]? ']' + * ; */ var tokenStream = this._tokenStream, value = null, + ns, token; - if(tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])){ + if (tokenStream.match(Tokens.LBRACKET)) { token = tokenStream.token(); - value = new Combinator(token.value, token.startLine, token.startCol); - this._readWhitespace(); - } + value = token.value; + value += this._readWhitespace(); - return value; - }, + ns = this._namespace_prefix(); - _unary_operator: function(){ + if (ns) { + value += ns; + } - /* - * unary_operator - * : '-' | '+' - * ; - */ + tokenStream.mustMatch(Tokens.IDENT); + value += tokenStream.token().value; + value += this._readWhitespace(); - var tokenStream = this._tokenStream; + if (tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH, + Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])) { - if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){ - return tokenStream.token().value; + value += tokenStream.token().value; + value += this._readWhitespace(); + + tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); + value += tokenStream.token().value; + value += this._readWhitespace(); + } + + tokenStream.mustMatch(Tokens.RBRACKET); + + return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol); } else { return null; } }, - _property: function(){ + // CSS3 Selectors + _pseudo: function() { /* - * property - * : IDENT S* + * pseudo + * : ':' ':'? [ IDENT | functional_pseudo ] * ; */ var tokenStream = this._tokenStream, - value = null, - hack = null, - tokenValue, - token, + pseudo = null, + colons = ":", line, col; - //check for star hack - throws error if not allowed - if (tokenStream.peek() == Tokens.STAR && this.options.starHack){ - tokenStream.get(); - token = tokenStream.token(); - hack = token.value; - line = token.startLine; - col = token.startCol; - } + if (tokenStream.match(Tokens.COLON)) { - if(tokenStream.match(Tokens.IDENT)){ - token = tokenStream.token(); - tokenValue = token.value; + if (tokenStream.match(Tokens.COLON)) { + colons += ":"; + } - //check for underscore hack - no error if not allowed because it's valid CSS syntax - if (tokenValue.charAt(0) == "_" && this.options.underscoreHack){ - hack = "_"; - tokenValue = tokenValue.substring(1); + if (tokenStream.match(Tokens.IDENT)) { + pseudo = tokenStream.token().value; + line = tokenStream.token().startLine; + col = tokenStream.token().startCol - colons.length; + } else if (tokenStream.peek() === Tokens.FUNCTION) { + line = tokenStream.LT(1).startLine; + col = tokenStream.LT(1).startCol - colons.length; + pseudo = this._functional_pseudo(); } - value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol)); - this._readWhitespace(); + if (pseudo) { + pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col); + } else { + var startLine = tokenStream.LT(1).startLine, + startCol = tokenStream.LT(0).startCol; + throw new SyntaxError("Expected a `FUNCTION` or `IDENT` after colon at line " + startLine + ", col " + startCol + ".", startLine, startCol); + } } - return value; + return pseudo; }, - //Augmented with CSS3 Selectors - _ruleset: function(){ + // CSS3 Selectors + _functional_pseudo: function() { /* - * ruleset - * : selectors_group - * '{' S* declaration? [ ';' S* declaration? ]* '}' S* + * functional_pseudo + * : FUNCTION S* expression ')' * ; - */ + */ var tokenStream = this._tokenStream, - tt, - selectors; + value = null; + + if (tokenStream.match(Tokens.FUNCTION)) { + value = tokenStream.token().value; + value += this._readWhitespace(); + value += this._expression(); + tokenStream.mustMatch(Tokens.RPAREN); + value += ")"; + } + return value; + }, + // CSS3 Selectors + _expression: function() { /* - * Error Recovery: If even a single selector fails to parse, - * then the entire ruleset should be thrown away. - */ - try { - selectors = this._selectors_group(); - } catch (ex){ - if (ex instanceof SyntaxError && !this.options.strict){ - - //fire error event - this.fire({ - type: "error", - error: ex, - message: ex.message, - line: ex.line, - col: ex.col - }); - - //skip over everything until closing brace - tt = tokenStream.advance([Tokens.RBRACE]); - if (tt == Tokens.RBRACE){ - //if there's a right brace, the rule is finished so don't do anything - } else { - //otherwise, rethrow the error because it wasn't handled properly - throw ex; - } - - } else { - //not a syntax error, rethrow it - throw ex; - } - - //trigger parser to continue - return true; - } - - //if it got here, all selectors parsed - if (selectors){ - - this.fire({ - type: "startrule", - selectors: selectors, - line: selectors[0].line, - col: selectors[0].col - }); - - this._readDeclarations(true); - - this.fire({ - type: "endrule", - selectors: selectors, - line: selectors[0].line, - col: selectors[0].col - }); - - } - - return selectors; - - }, - - //CSS3 Selectors - _selectors_group: function(){ - - /* - * selectors_group - * : selector [ COMMA S* selector ]* + * expression + * : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+ * ; */ + var tokenStream = this._tokenStream, - selectors = [], - selector; + value = ""; - selector = this._selector(); - if (selector !== null){ + while (tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION, + Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH, + Tokens.FREQ, Tokens.ANGLE, Tokens.TIME, + Tokens.RESOLUTION, Tokens.SLASH])) { - selectors.push(selector); - while(tokenStream.match(Tokens.COMMA)){ - this._readWhitespace(); - selector = this._selector(); - if (selector !== null){ - selectors.push(selector); - } else { - this._unexpectedToken(tokenStream.LT(1)); - } - } + value += tokenStream.token().value; + value += this._readWhitespace(); } - return selectors.length ? selectors : null; + return value.length ? value : null; + }, - //CSS3 Selectors - _selector: function(){ + // CSS3 Selectors + _negation: function() { /* - * selector - * : simple_selector_sequence [ combinator simple_selector_sequence ]* + * negation + * : NOT S* negation_arg S* ')' * ; */ var tokenStream = this._tokenStream, - selector = [], - nextSelector = null, - combinator = null, - ws = null; - - //if there's no simple selector, then there's no selector - nextSelector = this._simple_selector_sequence(); - if (nextSelector === null){ - return null; - } - - selector.push(nextSelector); - - do { - - //look for a combinator - combinator = this._combinator(); - - if (combinator !== null){ - selector.push(combinator); - nextSelector = this._simple_selector_sequence(); - - //there must be a next selector - if (nextSelector === null){ - this._unexpectedToken(tokenStream.LT(1)); - } else { - - //nextSelector is an instance of SelectorPart - selector.push(nextSelector); - } - } else { - - //if there's not whitespace, we're done - if (this._readWhitespace()){ - - //add whitespace separator - ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol); - - //combinator is not required - combinator = this._combinator(); - - //selector is required if there's a combinator - nextSelector = this._simple_selector_sequence(); - if (nextSelector === null){ - if (combinator !== null){ - this._unexpectedToken(tokenStream.LT(1)); - } - } else { - - if (combinator !== null){ - selector.push(combinator); - } else { - selector.push(ws); - } + line, + col, + value = "", + arg, + subpart = null; - selector.push(nextSelector); - } - } else { - break; - } + if (tokenStream.match(Tokens.NOT)) { + value = tokenStream.token().value; + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + value += this._readWhitespace(); + arg = this._negation_arg(); + value += arg; + value += this._readWhitespace(); + tokenStream.match(Tokens.RPAREN); + value += tokenStream.token().value; - } - } while(true); + subpart = new SelectorSubPart(value, "not", line, col); + subpart.args.push(arg); + } - return new Selector(selector, selector[0].line, selector[0].col); + return subpart; }, - //CSS3 Selectors - _simple_selector_sequence: function(){ + // CSS3 Selectors + _negation_arg: function() { /* - * simple_selector_sequence - * : [ type_selector | universal ] - * [ HASH | class | attrib | pseudo | negation ]* - * | [ HASH | class | attrib | pseudo | negation ]+ + * negation_arg + * : type_selector | universal | HASH | class | attrib | pseudo * ; */ var tokenStream = this._tokenStream, - - //parts of a simple selector - elementName = null, - modifiers = [], - - //complete selector text - selectorText= "", - - //the different parts after the element name to search for - components = [ - //HASH - function(){ + args = [ + this._type_selector, + this._universal, + function() { return tokenStream.match(Tokens.HASH) ? new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : null; }, this._class, this._attrib, - this._pseudo, - this._negation + this._pseudo ], + arg = null, i = 0, - len = components.length, - component = null, - found = false, + len = args.length, line, - col; - + col, + part; - //get starting line and column for the selector line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; - elementName = this._type_selector(); - if (!elementName){ - elementName = this._universal(); - } + while (i < len && arg === null) { - if (elementName !== null){ - selectorText += elementName; + arg = args[i].call(this); + i++; } - while(true){ - - //whitespace means we're done - if (tokenStream.peek() === Tokens.S){ - break; - } - - //check for each component - while(i < len && component === null){ - component = components[i++].call(this); - } - - if (component === null){ - - //we don't have a selector - if (selectorText === ""){ - return null; - } else { - break; - } - } else { - i = 0; - modifiers.push(component); - selectorText += component.toString(); - component = null; - } + // must be a negation arg + if (arg === null) { + this._unexpectedToken(tokenStream.LT(1)); } + // it's an element name + if (arg.type === "elementName") { + part = new SelectorPart(arg, [], arg.toString(), line, col); + } else { + part = new SelectorPart(null, [arg], arg.toString(), line, col); + } - return selectorText !== "" ? - new SelectorPart(elementName, modifiers, selectorText, line, col) : - null; + return part; }, - //CSS3 Selectors - _type_selector: function(){ + _declaration: function() { + /* - * type_selector - * : [ namespace_prefix ]? element_name + * declaration + * : property ':' S* expr prio? + * | /( empty )/ * ; */ - var tokenStream = this._tokenStream, - ns = this._namespace_prefix(), - elementName = this._element_name(); + var tokenStream = this._tokenStream, + property = null, + expr = null, + prio = null, + invalid = null, + propertyName = ""; + + property = this._property(); + if (property !== null) { + + tokenStream.mustMatch(Tokens.COLON); + this._readWhitespace(); + + expr = this._expr(); + + // if there's no parts for the value, it's an error + if (!expr || expr.length === 0) { + this._unexpectedToken(tokenStream.LT(1)); + } + + prio = this._prio(); - if (!elementName){ /* - * Need to back out the namespace that was read due to both - * type_selector and universal reading namespace_prefix - * first. Kind of hacky, but only way I can figure out - * right now how to not change the grammar. + * If hacks should be allowed, then only check the root + * property. If hacks should not be allowed, treat + * _property or *property as invalid properties. */ - if (ns){ - tokenStream.unget(); - if (ns.length > 1){ - tokenStream.unget(); - } + propertyName = property.toString(); + if (this.options.starHack && property.hack === "*" || + this.options.underscoreHack && property.hack === "_") { + + propertyName = property.text; } - return null; - } else { - if (ns){ - elementName.text = ns + elementName.text; - elementName.col -= ns.length; + try { + this._validateProperty(propertyName, expr); + } catch (ex) { + invalid = ex; } - return elementName; + + this.fire({ + type: "property", + property: property, + value: expr, + important: prio, + line: property.line, + col: property.col, + invalid: invalid + }); + + return true; + } else { + return false; } }, - //CSS3 Selectors - _class: function(){ + _prio: function() { /* - * class - * : '.' IDENT + * prio + * : IMPORTANT_SYM S* * ; */ var tokenStream = this._tokenStream, - token; - - if (tokenStream.match(Tokens.DOT)){ - tokenStream.mustMatch(Tokens.IDENT); - token = tokenStream.token(); - return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1); - } else { - return null; - } + result = tokenStream.match(Tokens.IMPORTANT_SYM); + this._readWhitespace(); + return result; }, - //CSS3 Selectors - _element_name: function(){ + _expr: function(inFunction) { /* - * element_name - * : IDENT + * expr + * : term [ operator term ]* * ; */ - var tokenStream = this._tokenStream, - token; - - if (tokenStream.match(Tokens.IDENT)){ - token = tokenStream.token(); - return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol); + var values = [], + //valueParts = [], + value = null, + operator = null; - } else { - return null; - } - }, + value = this._term(inFunction); + if (value !== null) { - //CSS3 Selectors - _namespace_prefix: function(){ - /* - * namespace_prefix - * : [ IDENT | '*' ]? '|' - * ; - */ - var tokenStream = this._tokenStream, - value = ""; + values.push(value); - //verify that this is a namespace prefix - if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){ + do { + operator = this._operator(inFunction); - if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){ - value += tokenStream.token().value; - } + // if there's an operator, keep building up the value parts + if (operator) { + values.push(operator); + } /*else { + // if there's not an operator, you have a full value + values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); + valueParts = []; + }*/ - tokenStream.mustMatch(Tokens.PIPE); - value += "|"; + value = this._term(inFunction); + if (value === null) { + break; + } else { + values.push(value); + } + } while (true); } - return value.length ? value : null; + // cleanup + /*if (valueParts.length) { + values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); + }*/ + + return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null; }, - //CSS3 Selectors - _universal: function(){ + _term: function(inFunction) { + /* - * universal - * : [ namespace_prefix ]? '*' + * term + * : unary_operator? + * [ NUMBER S* | PERCENTAGE S* | LENGTH S* | ANGLE S* | + * TIME S* | FREQ S* | function | ie_function ] + * | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor * ; */ - var tokenStream = this._tokenStream, - value = "", - ns; - ns = this._namespace_prefix(); - if(ns){ - value += ns; - } + var tokenStream = this._tokenStream, + unary = null, + value = null, + endChar = null, + part = null, + token, + line, + col; - if(tokenStream.match(Tokens.STAR)){ - value += "*"; + // returns the operator or null + unary = this._unary_operator(); + if (unary !== null) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; } - return value.length ? value : null; - - }, + // exception for IE filters + if (tokenStream.peek() === Tokens.IE_FUNCTION && this.options.ieFilters) { - //CSS3 Selectors - _attrib: function(){ - /* - * attrib - * : '[' S* [ namespace_prefix ]? IDENT S* - * [ [ PREFIXMATCH | - * SUFFIXMATCH | - * SUBSTRINGMATCH | - * '=' | - * INCLUDES | - * DASHMATCH ] S* [ IDENT | STRING ] S* - * ]? ']' - * ; - */ + value = this._ie_function(); + if (unary === null) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + } - var tokenStream = this._tokenStream, - value = null, - ns, - token; + // see if it's a simple block + } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])) { - if (tokenStream.match(Tokens.LBRACKET)){ token = tokenStream.token(); - value = token.value; - value += this._readWhitespace(); + endChar = token.endChar; + value = token.value + this._expr(inFunction).text; + if (unary === null) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + } + tokenStream.mustMatch(Tokens.type(endChar)); + value += endChar; + this._readWhitespace(); - ns = this._namespace_prefix(); + // see if there's a simple match + } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH, + Tokens.ANGLE, Tokens.TIME, + Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])) { - if (ns){ - value += ns; + value = tokenStream.token().value; + if (unary === null) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + // Correct potentially-inaccurate IDENT parsing in + // PropertyValuePart constructor. + part = PropertyValuePart.fromToken(tokenStream.token()); } + this._readWhitespace(); + } else { - tokenStream.mustMatch(Tokens.IDENT); - value += tokenStream.token().value; - value += this._readWhitespace(); + // see if it's a color + token = this._hexcolor(); + if (token === null) { - if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH, - Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){ + // if there's no unary, get the start of the next token for line/col info + if (unary === null) { + line = tokenStream.LT(1).startLine; + col = tokenStream.LT(1).startCol; + } - value += tokenStream.token().value; - value += this._readWhitespace(); + // has to be a function + if (value === null) { - tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); - value += tokenStream.token().value; - value += this._readWhitespace(); - } + /* + * This checks for alpha(opacity=0) style of IE + * functions. IE_FUNCTION only presents progid: style. + */ + if (tokenStream.LA(3) === Tokens.EQUALS && this.options.ieFilters) { + value = this._ie_function(); + } else { + value = this._function(); + } + } - tokenStream.mustMatch(Tokens.RBRACKET); + /*if (value === null) { + return null; + //throw new Error("Expected identifier at line " + tokenStream.token().startLine + ", character " + tokenStream.token().startCol + "."); + }*/ + + } else { + value = token.value; + if (unary === null) { + line = token.startLine; + col = token.startCol; + } + } - return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol); - } else { - return null; } + + return part !== null ? part : value !== null ? + new PropertyValuePart(unary !== null ? unary + value : value, line, col) : + null; + }, - //CSS3 Selectors - _pseudo: function(){ + _function: function() { /* - * pseudo - * : ':' ':'? [ IDENT | functional_pseudo ] + * function + * : FUNCTION S* expr ')' S* * ; */ var tokenStream = this._tokenStream, - pseudo = null, - colons = ":", - line, - col; + functionText = null, + expr = null, + lt; - if (tokenStream.match(Tokens.COLON)){ + if (tokenStream.match(Tokens.FUNCTION)) { + functionText = tokenStream.token().value; + this._readWhitespace(); + expr = this._expr(true); + functionText += expr; - if (tokenStream.match(Tokens.COLON)){ - colons += ":"; - } + // START: Horrible hack in case it's an IE filter + if (this.options.ieFilters && tokenStream.peek() === Tokens.EQUALS) { + do { - if (tokenStream.match(Tokens.IDENT)){ - pseudo = tokenStream.token().value; - line = tokenStream.token().startLine; - col = tokenStream.token().startCol - colons.length; - } else if (tokenStream.peek() == Tokens.FUNCTION){ - line = tokenStream.LT(1).startLine; - col = tokenStream.LT(1).startCol - colons.length; - pseudo = this._functional_pseudo(); - } + if (this._readWhitespace()) { + functionText += tokenStream.token().value; + } - if (pseudo){ - pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col); - } - } + // might be second time in the loop + if (tokenStream.LA(0) === Tokens.COMMA) { + functionText += tokenStream.token().value; + } - return pseudo; - }, + tokenStream.match(Tokens.IDENT); + functionText += tokenStream.token().value; - //CSS3 Selectors - _functional_pseudo: function(){ - /* - * functional_pseudo - * : FUNCTION S* expression ')' - * ; - */ + tokenStream.match(Tokens.EQUALS); + functionText += tokenStream.token().value; - var tokenStream = this._tokenStream, - value = null; + //functionText += this._term(); + lt = tokenStream.peek(); + while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) { + tokenStream.get(); + functionText += tokenStream.token().value; + lt = tokenStream.peek(); + } + } while (tokenStream.match([Tokens.COMMA, Tokens.S])); + } - if(tokenStream.match(Tokens.FUNCTION)){ - value = tokenStream.token().value; - value += this._readWhitespace(); - value += this._expression(); - tokenStream.mustMatch(Tokens.RPAREN); - value += ")"; + // END: Horrible Hack + + tokenStream.match(Tokens.RPAREN); + functionText += ")"; + this._readWhitespace(); } - return value; + return functionText; }, - //CSS3 Selectors - _expression: function(){ - /* - * expression - * : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+ + _ie_function: function() { + + /* (My own extension) + * ie_function + * : IE_FUNCTION S* IDENT '=' term [S* ','? IDENT '=' term]+ ')' S* * ; */ var tokenStream = this._tokenStream, - value = ""; + functionText = null, + lt; - while(tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION, - Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH, - Tokens.FREQ, Tokens.ANGLE, Tokens.TIME, - Tokens.RESOLUTION, Tokens.SLASH])){ + // IE function can begin like a regular function, too + if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])) { + functionText = tokenStream.token().value; - value += tokenStream.token().value; - value += this._readWhitespace(); - } + do { - return value.length ? value : null; + if (this._readWhitespace()) { + functionText += tokenStream.token().value; + } - }, + // might be second time in the loop + if (tokenStream.LA(0) === Tokens.COMMA) { + functionText += tokenStream.token().value; + } - //CSS3 Selectors - _negation: function(){ - /* - * negation - * : NOT S* negation_arg S* ')' - * ; - */ + tokenStream.match(Tokens.IDENT); + functionText += tokenStream.token().value; - var tokenStream = this._tokenStream, - line, - col, - value = "", - arg, - subpart = null; + tokenStream.match(Tokens.EQUALS); + functionText += tokenStream.token().value; - if (tokenStream.match(Tokens.NOT)){ - value = tokenStream.token().value; - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; - value += this._readWhitespace(); - arg = this._negation_arg(); - value += arg; - value += this._readWhitespace(); - tokenStream.match(Tokens.RPAREN); - value += tokenStream.token().value; + //functionText += this._term(); + lt = tokenStream.peek(); + while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) { + tokenStream.get(); + functionText += tokenStream.token().value; + lt = tokenStream.peek(); + } + } while (tokenStream.match([Tokens.COMMA, Tokens.S])); - subpart = new SelectorSubPart(value, "not", line, col); - subpart.args.push(arg); + tokenStream.match(Tokens.RPAREN); + functionText += ")"; + this._readWhitespace(); } - return subpart; + return functionText; }, - //CSS3 Selectors - _negation_arg: function(){ + _hexcolor: function() { /* - * negation_arg - * : type_selector | universal | HASH | class | attrib | pseudo + * There is a constraint on the color that it must + * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) + * after the "#"; e.g., "#000" is OK, but "#abcd" is not. + * + * hexcolor + * : HASH S* * ; */ var tokenStream = this._tokenStream, - args = [ - this._type_selector, - this._universal, - function(){ - return tokenStream.match(Tokens.HASH) ? - new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : - null; - }, - this._class, - this._attrib, - this._pseudo - ], - arg = null, - i = 0, - len = args.length, - elementName, - line, - col, - part; - - line = tokenStream.LT(1).startLine; - col = tokenStream.LT(1).startCol; - - while(i < len && arg === null){ + token = null, + color; - arg = args[i].call(this); - i++; - } + if (tokenStream.match(Tokens.HASH)) { - //must be a negation arg - if (arg === null){ - this._unexpectedToken(tokenStream.LT(1)); - } + // need to do some validation here - //it's an element name - if (arg.type == "elementName"){ - part = new SelectorPart(arg, [], arg.toString(), line, col); - } else { - part = new SelectorPart(null, [arg], arg.toString(), line, col); + token = tokenStream.token(); + color = token.value; + if (!/#[a-f0-9]{3,6}/i.test(color)) { + throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); + } + this._readWhitespace(); } - return part; + return token; }, - _declaration: function(){ + //----------------------------------------------------------------- + // Animations methods + //----------------------------------------------------------------- + + _keyframes: function() { /* - * declaration - * : property ':' S* expr prio? - * | /( empty )/ + * keyframes: + * : KEYFRAMES_SYM S* keyframe_name S* '{' S* keyframe_rule* '}' { * ; */ - var tokenStream = this._tokenStream, - property = null, - expr = null, - prio = null, - error = null, - invalid = null, - propertyName= ""; - - property = this._property(); - if (property !== null){ + token, + tt, + name, + prefix = ""; - tokenStream.mustMatch(Tokens.COLON); - this._readWhitespace(); + tokenStream.mustMatch(Tokens.KEYFRAMES_SYM); + token = tokenStream.token(); + if (/^@-([^-]+)-/.test(token.value)) { + prefix = RegExp.$1; + } - expr = this._expr(); + this._readWhitespace(); + name = this._keyframe_name(); - //if there's no parts for the value, it's an error - if (!expr || expr.length === 0){ - this._unexpectedToken(tokenStream.LT(1)); - } + this._readWhitespace(); + tokenStream.mustMatch(Tokens.LBRACE); - prio = this._prio(); + this.fire({ + type: "startkeyframes", + name: name, + prefix: prefix, + line: token.startLine, + col: token.startCol + }); - /* - * If hacks should be allowed, then only check the root - * property. If hacks should not be allowed, treat - * _property or *property as invalid properties. - */ - propertyName = property.toString(); - if (this.options.starHack && property.hack == "*" || - this.options.underscoreHack && property.hack == "_") { + this._readWhitespace(); + tt = tokenStream.peek(); - propertyName = property.text; - } + // check for key + while (tt === Tokens.IDENT || tt === Tokens.PERCENTAGE) { + this._keyframe_rule(); + this._readWhitespace(); + tt = tokenStream.peek(); + } - try { - this._validateProperty(propertyName, expr); - } catch (ex) { - invalid = ex; - } + this.fire({ + type: "endkeyframes", + name: name, + prefix: prefix, + line: token.startLine, + col: token.startCol + }); - this.fire({ - type: "property", - property: property, - value: expr, - important: prio, - line: property.line, - col: property.col, - invalid: invalid - }); + this._readWhitespace(); + tokenStream.mustMatch(Tokens.RBRACE); + this._readWhitespace(); - return true; - } else { - return false; - } }, - _prio: function(){ + _keyframe_name: function() { + /* - * prio - * : IMPORTANT_SYM S* + * keyframe_name: + * : IDENT + * | STRING * ; */ + var tokenStream = this._tokenStream; - var tokenStream = this._tokenStream, - result = tokenStream.match(Tokens.IMPORTANT_SYM); - - this._readWhitespace(); - return result; + tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); + return SyntaxUnit.fromToken(tokenStream.token()); }, - _expr: function(inFunction){ + _keyframe_rule: function() { + /* - * expr - * : term [ operator term ]* + * keyframe_rule: + * : key_list S* + * '{' S* declaration [ ';' S* declaration ]* '}' S* * ; */ + var keyList = this._key_list(); - var tokenStream = this._tokenStream, - values = [], - //valueParts = [], - value = null, - operator = null; + this.fire({ + type: "startkeyframerule", + keys: keyList, + line: keyList[0].line, + col: keyList[0].col + }); - value = this._term(inFunction); - if (value !== null){ + this._readDeclarations(true); - values.push(value); + this.fire({ + type: "endkeyframerule", + keys: keyList, + line: keyList[0].line, + col: keyList[0].col + }); - do { - operator = this._operator(inFunction); + }, - //if there's an operator, keep building up the value parts - if (operator){ - values.push(operator); - } /*else { - //if there's not an operator, you have a full value - values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); - valueParts = []; - }*/ + _key_list: function() { - value = this._term(inFunction); + /* + * key_list: + * : key [ S* ',' S* key]* + * ; + */ + var tokenStream = this._tokenStream, + keyList = []; - if (value === null){ - break; - } else { - values.push(value); - } - } while(true); - } + // must be least one key + keyList.push(this._key()); - //cleanup - /*if (valueParts.length){ - values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); - }*/ + this._readWhitespace(); - return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null; - }, + while (tokenStream.match(Tokens.COMMA)) { + this._readWhitespace(); + keyList.push(this._key()); + this._readWhitespace(); + } - _term: function(inFunction){ + return keyList; + }, + _key: function() { /* - * term - * : unary_operator? - * [ NUMBER S* | PERCENTAGE S* | LENGTH S* | ANGLE S* | - * TIME S* | FREQ S* | function | ie_function ] - * | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor + * There is a restriction that IDENT can be only "from" or "to". + * + * key + * : PERCENTAGE + * | IDENT * ; */ var tokenStream = this._tokenStream, - unary = null, - value = null, - endChar = null, - token, - line, - col; - - //returns the operator or null - unary = this._unary_operator(); - if (unary !== null){ - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; - } + token; - //exception for IE filters - if (tokenStream.peek() == Tokens.IE_FUNCTION && this.options.ieFilters){ + if (tokenStream.match(Tokens.PERCENTAGE)) { + return SyntaxUnit.fromToken(tokenStream.token()); + } else if (tokenStream.match(Tokens.IDENT)) { + token = tokenStream.token(); - value = this._ie_function(); - if (unary === null){ - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; + if (/from|to/i.test(token.value)) { + return SyntaxUnit.fromToken(token); } - //see if it's a simple block - } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])){ - - token = tokenStream.token(); - endChar = token.endChar; - value = token.value + this._expr(inFunction).text; - if (unary === null){ - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; - } - tokenStream.mustMatch(Tokens.type(endChar)); - value += endChar; - this._readWhitespace(); - - //see if there's a simple match - } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH, - Tokens.ANGLE, Tokens.TIME, - Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])){ - - value = tokenStream.token().value; - if (unary === null){ - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; - } - this._readWhitespace(); - } else { - - //see if it's a color - token = this._hexcolor(); - if (token === null){ - - //if there's no unary, get the start of the next token for line/col info - if (unary === null){ - line = tokenStream.LT(1).startLine; - col = tokenStream.LT(1).startCol; - } - - //has to be a function - if (value === null){ - - /* - * This checks for alpha(opacity=0) style of IE - * functions. IE_FUNCTION only presents progid: style. - */ - if (tokenStream.LA(3) == Tokens.EQUALS && this.options.ieFilters){ - value = this._ie_function(); - } else { - value = this._function(); - } - } + tokenStream.unget(); + } - /*if (value === null){ - return null; - //throw new Error("Expected identifier at line " + tokenStream.token().startLine + ", character " + tokenStream.token().startCol + "."); - }*/ + // if it gets here, there wasn't a valid token, so time to explode + this._unexpectedToken(tokenStream.LT(1)); + }, - } else { - value = token.value; - if (unary === null){ - line = token.startLine; - col = token.startCol; - } - } + //----------------------------------------------------------------- + // Helper methods + //----------------------------------------------------------------- + /** + * Not part of CSS grammar, but useful for skipping over + * combination of white space and HTML-style comments. + * @return {void} + * @method _skipCruft + * @private + */ + _skipCruft: function() { + while (this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])) { + // noop } - - return value !== null ? - new PropertyValuePart(unary !== null ? unary + value : value, line, col) : - null; - }, - _function: function(){ - + /** + * Not part of CSS grammar, but this pattern occurs frequently + * in the official CSS grammar. Split out here to eliminate + * duplicate code. + * @param {Boolean} checkStart Indicates if the rule should check + * for the left brace at the beginning. + * @param {Boolean} readMargins Indicates if the rule should check + * for margin patterns. + * @return {void} + * @method _readDeclarations + * @private + */ + _readDeclarations: function(checkStart, readMargins) { /* - * function - * : FUNCTION S* expr ')' S* - * ; + * Reads the pattern + * S* '{' S* declaration [ ';' S* declaration ]* '}' S* + * or + * S* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S* + * Note that this is how it is described in CSS3 Paged Media, but is actually incorrect. + * A semicolon is only necessary following a declaration if there's another declaration + * or margin afterwards. */ - var tokenStream = this._tokenStream, - functionText = null, - expr = null, - lt; + tt; - if (tokenStream.match(Tokens.FUNCTION)){ - functionText = tokenStream.token().value; - this._readWhitespace(); - expr = this._expr(true); - functionText += expr; - //START: Horrible hack in case it's an IE filter - if (this.options.ieFilters && tokenStream.peek() == Tokens.EQUALS){ - do { + this._readWhitespace(); - if (this._readWhitespace()){ - functionText += tokenStream.token().value; - } + if (checkStart) { + tokenStream.mustMatch(Tokens.LBRACE); + } - //might be second time in the loop - if (tokenStream.LA(0) == Tokens.COMMA){ - functionText += tokenStream.token().value; - } + this._readWhitespace(); - tokenStream.match(Tokens.IDENT); - functionText += tokenStream.token().value; + try { - tokenStream.match(Tokens.EQUALS); - functionText += tokenStream.token().value; + while (true) { - //functionText += this._term(); - lt = tokenStream.peek(); - while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){ - tokenStream.get(); - functionText += tokenStream.token().value; - lt = tokenStream.peek(); + if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())) { + // noop + } else if (this._declaration()) { + if (!tokenStream.match(Tokens.SEMICOLON)) { + break; } - } while(tokenStream.match([Tokens.COMMA, Tokens.S])); - } + } else { + break; + } - //END: Horrible Hack + //if ((!this._margin() && !this._declaration()) || !tokenStream.match(Tokens.SEMICOLON)) { + // break; + //} + this._readWhitespace(); + } - tokenStream.match(Tokens.RPAREN); - functionText += ")"; + tokenStream.mustMatch(Tokens.RBRACE); this._readWhitespace(); - } - - return functionText; - }, - _ie_function: function(){ - - /* (My own extension) - * ie_function - * : IE_FUNCTION S* IDENT '=' term [S* ','? IDENT '=' term]+ ')' S* - * ; - */ - - var tokenStream = this._tokenStream, - functionText = null, - expr = null, - lt; - - //IE function can begin like a regular function, too - if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])){ - functionText = tokenStream.token().value; + } catch (ex) { + if (ex instanceof SyntaxError && !this.options.strict) { - do { + // fire error event + this.fire({ + type: "error", + error: ex, + message: ex.message, + line: ex.line, + col: ex.col + }); - if (this._readWhitespace()){ - functionText += tokenStream.token().value; + // see if there's another declaration + tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]); + if (tt === Tokens.SEMICOLON) { + // if there's a semicolon, then there might be another declaration + this._readDeclarations(false, readMargins); + } else if (tt !== Tokens.EOF && tt !== Tokens.RBRACE) { + // if there's a right brace, the rule is finished so don't do anything + // otherwise, rethrow the error because it wasn't handled properly + throw ex; } - //might be second time in the loop - if (tokenStream.LA(0) == Tokens.COMMA){ - functionText += tokenStream.token().value; - } + } else { + // not a syntax error, rethrow it + throw ex; + } + } - tokenStream.match(Tokens.IDENT); - functionText += tokenStream.token().value; + }, - tokenStream.match(Tokens.EQUALS); - functionText += tokenStream.token().value; + /** + * In some cases, you can end up with two white space tokens in a + * row. Instead of making a change in every function that looks for + * white space, this function is used to match as much white space + * as necessary. + * @method _readWhitespace + * @return {String} The white space if found, empty string if not. + * @private + */ + _readWhitespace: function() { - //functionText += this._term(); - lt = tokenStream.peek(); - while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){ - tokenStream.get(); - functionText += tokenStream.token().value; - lt = tokenStream.peek(); - } - } while(tokenStream.match([Tokens.COMMA, Tokens.S])); + var tokenStream = this._tokenStream, + ws = ""; - tokenStream.match(Tokens.RPAREN); - functionText += ")"; - this._readWhitespace(); + while (tokenStream.match(Tokens.S)) { + ws += tokenStream.token().value; } - return functionText; + return ws; }, - _hexcolor: function(){ - /* - * There is a constraint on the color that it must - * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) - * after the "#"; e.g., "#000" is OK, but "#abcd" is not. - * - * hexcolor - * : HASH S* - * ; - */ - - var tokenStream = this._tokenStream, - token = null, - color; - - if(tokenStream.match(Tokens.HASH)){ - //need to do some validation here + /** + * Throws an error when an unexpected token is found. + * @param {Object} token The token that was found. + * @method _unexpectedToken + * @return {void} + * @private + */ + _unexpectedToken: function(token) { + throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); + }, - token = tokenStream.token(); - color = token.value; - if (!/#[a-f0-9]{3,6}/i.test(color)){ - throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); - } - this._readWhitespace(); + /** + * Helper method used for parsing subparts of a style sheet. + * @return {void} + * @method _verifyEnd + * @private + */ + _verifyEnd: function() { + if (this._tokenStream.LA(1) !== Tokens.EOF) { + this._unexpectedToken(this._tokenStream.LT(1)); } + }, - return token; + //----------------------------------------------------------------- + // Validation methods + //----------------------------------------------------------------- + _validateProperty: function(property, value) { + Validation.validate(property, value); }, //----------------------------------------------------------------- - // Animations methods + // Parsing methods //----------------------------------------------------------------- - _keyframes: function(){ + parse: function(input) { + this._tokenStream = new TokenStream(input, Tokens); + this._stylesheet(); + }, - /* - * keyframes: - * : KEYFRAMES_SYM S* keyframe_name S* '{' S* keyframe_rule* '}' { - * ; - */ - var tokenStream = this._tokenStream, - token, - tt, - name, - prefix = ""; + parseStyleSheet: function(input) { + // just passthrough + return this.parse(input); + }, - tokenStream.mustMatch(Tokens.KEYFRAMES_SYM); - token = tokenStream.token(); - if (/^@\-([^\-]+)\-/.test(token.value)) { - prefix = RegExp.$1; - } + parseMediaQuery: function(input) { + this._tokenStream = new TokenStream(input, Tokens); + var result = this._media_query(); - this._readWhitespace(); - name = this._keyframe_name(); + // if there's anything more, then it's an invalid selector + this._verifyEnd(); - this._readWhitespace(); - tokenStream.mustMatch(Tokens.LBRACE); + // otherwise return result + return result; + }, - this.fire({ - type: "startkeyframes", - name: name, - prefix: prefix, - line: token.startLine, - col: token.startCol - }); + /** + * Parses a property value (everything after the semicolon). + * @return {parserlib.css.PropertyValue} The property value. + * @throws parserlib.util.SyntaxError If an unexpected token is found. + * @method parserPropertyValue + */ + parsePropertyValue: function(input) { + this._tokenStream = new TokenStream(input, Tokens); this._readWhitespace(); - tt = tokenStream.peek(); - - //check for key - while(tt == Tokens.IDENT || tt == Tokens.PERCENTAGE) { - this._keyframe_rule(); - this._readWhitespace(); - tt = tokenStream.peek(); - } - this.fire({ - type: "endkeyframes", - name: name, - prefix: prefix, - line: token.startLine, - col: token.startCol - }); + var result = this._expr(); + // okay to have a trailing white space this._readWhitespace(); - tokenStream.mustMatch(Tokens.RBRACE); - - }, - - _keyframe_name: function(){ - - /* - * keyframe_name: - * : IDENT - * | STRING - * ; - */ - var tokenStream = this._tokenStream, - token; - - tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); - return SyntaxUnit.fromToken(tokenStream.token()); - }, - - _keyframe_rule: function(){ - - /* - * keyframe_rule: - * : key_list S* - * '{' S* declaration [ ';' S* declaration ]* '}' S* - * ; - */ - var tokenStream = this._tokenStream, - token, - keyList = this._key_list(); - - this.fire({ - type: "startkeyframerule", - keys: keyList, - line: keyList[0].line, - col: keyList[0].col - }); - - this._readDeclarations(true); - this.fire({ - type: "endkeyframerule", - keys: keyList, - line: keyList[0].line, - col: keyList[0].col - }); + // if there's anything more, then it's an invalid selector + this._verifyEnd(); + // otherwise return result + return result; }, - _key_list: function(){ + /** + * Parses a complete CSS rule, including selectors and + * properties. + * @param {String} input The text to parser. + * @return {Boolean} True if the parse completed successfully, false if not. + * @method parseRule + */ + parseRule: function(input) { + this._tokenStream = new TokenStream(input, Tokens); - /* - * key_list: - * : key [ S* ',' S* key]* - * ; - */ - var tokenStream = this._tokenStream, - token, - key, - keyList = []; + // skip any leading white space + this._readWhitespace(); - //must be least one key - keyList.push(this._key()); + var result = this._ruleset(); + // skip any trailing white space this._readWhitespace(); - while(tokenStream.match(Tokens.COMMA)){ - this._readWhitespace(); - keyList.push(this._key()); - this._readWhitespace(); - } + // if there's anything more, then it's an invalid selector + this._verifyEnd(); - return keyList; + // otherwise return result + return result; }, - _key: function(){ - /* - * There is a restriction that IDENT can be only "from" or "to". - * - * key - * : PERCENTAGE - * | IDENT - * ; - */ - - var tokenStream = this._tokenStream, - token; + /** + * Parses a single CSS selector (no comma) + * @param {String} input The text to parse as a CSS selector. + * @return {Selector} An object representing the selector. + * @throws parserlib.util.SyntaxError If an unexpected token is found. + * @method parseSelector + */ + parseSelector: function(input) { - if (tokenStream.match(Tokens.PERCENTAGE)){ - return SyntaxUnit.fromToken(tokenStream.token()); - } else if (tokenStream.match(Tokens.IDENT)){ - token = tokenStream.token(); + this._tokenStream = new TokenStream(input, Tokens); - if (/from|to/i.test(token.value)){ - return SyntaxUnit.fromToken(token); - } + // skip any leading white space + this._readWhitespace(); - tokenStream.unget(); - } + var result = this._selector(); - //if it gets here, there wasn't a valid token, so time to explode - this._unexpectedToken(tokenStream.LT(1)); - }, + // skip any trailing white space + this._readWhitespace(); - //----------------------------------------------------------------- - // Helper methods - //----------------------------------------------------------------- + // if there's anything more, then it's an invalid selector + this._verifyEnd(); - /** - * Not part of CSS grammar, but useful for skipping over - * combination of white space and HTML-style comments. - * @return {void} - * @method _skipCruft - * @private - */ - _skipCruft: function(){ - while(this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])){ - //noop - } + // otherwise return result + return result; }, /** - * Not part of CSS grammar, but this pattern occurs frequently - * in the official CSS grammar. Split out here to eliminate - * duplicate code. - * @param {Boolean} checkStart Indicates if the rule should check - * for the left brace at the beginning. - * @param {Boolean} readMargins Indicates if the rule should check - * for margin patterns. + * Parses an HTML style attribute: a set of CSS declarations + * separated by semicolons. + * @param {String} input The text to parse as a style attribute * @return {void} - * @method _readDeclarations - * @private + * @method parseStyleAttribute */ - _readDeclarations: function(checkStart, readMargins){ - /* - * Reads the pattern - * S* '{' S* declaration [ ';' S* declaration ]* '}' S* - * or - * S* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S* - * Note that this is how it is described in CSS3 Paged Media, but is actually incorrect. - * A semicolon is only necessary following a declaration is there's another declaration - * or margin afterwards. - */ - var tokenStream = this._tokenStream, - tt; - + parseStyleAttribute: function(input) { + input += "}"; // for error recovery in _readDeclarations() + this._tokenStream = new TokenStream(input, Tokens); + this._readDeclarations(); + } + }; - this._readWhitespace(); + // copy over onto prototype + for (prop in additions) { + if (Object.prototype.hasOwnProperty.call(additions, prop)) { + proto[prop] = additions[prop]; + } + } - if (checkStart){ - tokenStream.mustMatch(Tokens.LBRACE); - } + return proto; +}(); - this._readWhitespace(); - try { +/* +nth + : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? | + ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S* + ; +*/ - while(true){ +},{"../util/EventTarget":23,"../util/SyntaxError":25,"../util/SyntaxUnit":26,"./Combinator":2,"./MediaFeature":4,"./MediaQuery":5,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./TokenStream":17,"./Tokens":18,"./Validation":19}],7:[function(require,module,exports){ +/* exported Properties */ + +"use strict"; + +var Properties = module.exports = { + __proto__: null, + + // A + "align-items" : "flex-start | flex-end | center | baseline | stretch", + "align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", + "align-self" : "auto | flex-start | flex-end | center | baseline | stretch", + "all" : "initial | inherit | unset", + "-webkit-align-items" : "flex-start | flex-end | center | baseline | stretch", + "-webkit-align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", + "-webkit-align-self" : "auto | flex-start | flex-end | center | baseline | stretch", + "alignment-adjust" : "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | ", + "alignment-baseline" : "auto | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical", + "animation" : 1, + "animation-delay" : "
    • ', - '

      juhu', - '

      ', - 'kinners', - '

    • ' - ]); - - var mode = new HtmlMode(); - session.setMode(mode); - session.setFoldStyle("markbeginend"); - - assert.equal(session.getFoldWidget(0), "start"); - assert.equal(session.getFoldWidget(1), "start"); - assert.equal(session.getFoldWidget(2), "start"); - assert.equal(session.getFoldWidget(3), "start"); - assert.equal(session.getFoldWidget(4), ""); - assert.equal(session.getFoldWidget(5), "end"); - - assert.range(session.getFoldWidgetRange(1), 1, 4, 5, 0); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) - require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/mode/folding/ini.js b/lib/ace/mode/folding/ini.js deleted file mode 100644 index ef4eaa0b1d7..00000000000 --- a/lib/ace/mode/folding/ini.js +++ /dev/null @@ -1,80 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var Range = require("../../range").Range; -var BaseFoldMode = require("./fold_mode").FoldMode; - -var FoldMode = exports.FoldMode = function() { -}; -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - - this.foldingStartMarker = /^\s*\[([^\])]*)]\s*(?:$|[;#])/; - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var re = this.foldingStartMarker; - var line = session.getLine(row); - - var m = line.match(re); - - if (!m) return; - - var startName = m[1] + "."; - - var startColumn = line.length; - var maxRow = session.getLength(); - var startRow = row; - var endRow = row; - - while (++row < maxRow) { - line = session.getLine(row); - if (/^\s*$/.test(line)) - continue; - m = line.match(re); - if (m && m[1].lastIndexOf(startName, 0) !== 0) - break; - - endRow = row; - } - - if (endRow > startRow) { - var endColumn = session.getLine(endRow).length; - return new Range(startRow, startColumn, endRow, endColumn); - } - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/latex.js b/lib/ace/mode/folding/latex.js deleted file mode 100644 index e399cccdbe5..00000000000 --- a/lib/ace/mode/folding/latex.js +++ /dev/null @@ -1,180 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var BaseFoldMode = require("./fold_mode").FoldMode; -var Range = require("../../range").Range; -var TokenIterator = require("../../token_iterator").TokenIterator; -var keywordLevels = { - "\\subparagraph": 1, - "\\paragraph": 2, - "\\subsubsubsection": 3, - "\\subsubsection": 4, - "\\subsection": 5, - "\\section": 6, - "\\chapter": 7, - "\\part": 8, - "\\begin": 9, - "\\end": 10 -}; - -var FoldMode = exports.FoldMode = function() {}; - -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - - this.foldingStartMarker = /^\s*\\(begin)|\s*\\(part|chapter|(?:sub)*(?:section|paragraph))\b|{\s*$/; - this.foldingStopMarker = /^\s*\\(end)\b|^\s*}/; - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var line = session.doc.getLine(row); - var match = this.foldingStartMarker.exec(line); - if (match) { - if (match[1]) - return this.latexBlock(session, row, match[0].length - 1); - if (match[2]) - return this.latexSection(session, row, match[0].length - 1); - - return this.openingBracketBlock(session, "{", row, match.index); - } - - var match = this.foldingStopMarker.exec(line); - if (match) { - if (match[1]) - return this.latexBlock(session, row, match[0].length - 1); - - return this.closingBracketBlock(session, "}", row, match.index + match[0].length); - } - }; - - this.latexBlock = function(session, row, column, returnRange) { - var keywords = { - "\\begin": 1, - "\\end": -1 - }; - - var stream = new TokenIterator(session, row, column); - var token = stream.getCurrentToken(); - if (!token || !(token.type == "storage.type" || token.type == "constant.character.escape")) - return; - - var val = token.value; - var dir = keywords[val]; - - var getType = function() { - var token = stream.stepForward(); - var type = token.type == "lparen" ?stream.stepForward().value : ""; - if (dir === -1) { - stream.stepBackward(); - if (type) - stream.stepBackward(); - } - return type; - }; - var stack = [getType()]; - var startColumn = dir === -1 ? stream.getCurrentTokenColumn() : session.getLine(row).length; - var startRow = row; - - stream.step = dir === -1 ? stream.stepBackward : stream.stepForward; - while(token = stream.step()) { - if (!token || !(token.type == "storage.type" || token.type == "constant.character.escape")) - continue; - var level = keywords[token.value]; - if (!level) - continue; - var type = getType(); - if (level === dir) - stack.unshift(type); - else if (stack.shift() !== type || !stack.length) - break; - } - - if (stack.length) - return; - - if (dir == 1) { - stream.stepBackward(); - stream.stepBackward(); - } - - if (returnRange) - return stream.getCurrentTokenRange(); - - var row = stream.getCurrentTokenRow(); - if (dir === -1) - return new Range(row, session.getLine(row).length, startRow, startColumn); - else - return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn()); - }; - - this.latexSection = function(session, row, column) { - var stream = new TokenIterator(session, row, column); - var token = stream.getCurrentToken(); - if (!token || token.type != "storage.type") - return; - - var startLevel = keywordLevels[token.value] || 0; - var stackDepth = 0; - var endRow = row; - - while(token = stream.stepForward()) { - if (token.type !== "storage.type") - continue; - var level = keywordLevels[token.value] || 0; - - if (level >= 9) { - if (!stackDepth) - endRow = stream.getCurrentTokenRow() - 1; - stackDepth += level == 9 ? 1 : - 1; - if (stackDepth < 0) - break; - } else if (level >= startLevel) - break; - } - - if (!stackDepth) - endRow = stream.getCurrentTokenRow() - 1; - - while (endRow > row && !/\S/.test(session.getLine(endRow))) - endRow--; - - return new Range( - row, session.getLine(row).length, - endRow, session.getLine(endRow).length - ); - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/lua.js b/lib/ace/mode/folding/lua.js deleted file mode 100644 index f4b52334259..00000000000 --- a/lib/ace/mode/folding/lua.js +++ /dev/null @@ -1,163 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var BaseFoldMode = require("./fold_mode").FoldMode; -var Range = require("../../range").Range; -var TokenIterator = require("../../token_iterator").TokenIterator; - - -var FoldMode = exports.FoldMode = function() {}; - -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - - this.foldingStartMarker = /\b(function|then|do|repeat)\b|{\s*$|(\[=*\[)/; - this.foldingStopMarker = /\bend\b|^\s*}|\]=*\]/; - - this.getFoldWidget = function(session, foldStyle, row) { - var line = session.getLine(row); - var isStart = this.foldingStartMarker.test(line); - var isEnd = this.foldingStopMarker.test(line); - - if (isStart && !isEnd) { - var match = line.match(this.foldingStartMarker); - if (match[1] == "then" && /\belseif\b/.test(line)) - return; - if (match[1]) { - if (session.getTokenAt(row, match.index + 1).type === "keyword") - return "start"; - } else if (match[2]) { - var type = session.bgTokenizer.getState(row) || ""; - if (type[0] == "bracketedComment" || type[0] == "bracketedString") - return "start"; - } else { - return "start"; - } - } - if (foldStyle != "markbeginend" || !isEnd || isStart && isEnd) - return ""; - - var match = line.match(this.foldingStopMarker); - if (match[0] === "end") { - if (session.getTokenAt(row, match.index + 1).type === "keyword") - return "end"; - } else if (match[0][0] === "]") { - var type = session.bgTokenizer.getState(row - 1) || ""; - if (type[0] == "bracketedComment" || type[0] == "bracketedString") - return "end"; - } else - return "end"; - }; - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var line = session.doc.getLine(row); - var match = this.foldingStartMarker.exec(line); - if (match) { - if (match[1]) - return this.luaBlock(session, row, match.index + 1); - - if (match[2]) - return session.getCommentFoldRange(row, match.index + 1); - - return this.openingBracketBlock(session, "{", row, match.index); - } - - var match = this.foldingStopMarker.exec(line); - if (match) { - if (match[0] === "end") { - if (session.getTokenAt(row, match.index + 1).type === "keyword") - return this.luaBlock(session, row, match.index + 1); - } - - if (match[0][0] === "]") - return session.getCommentFoldRange(row, match.index + 1); - - return this.closingBracketBlock(session, "}", row, match.index + match[0].length); - } - }; - - this.luaBlock = function(session, row, column) { - var stream = new TokenIterator(session, row, column); - var indentKeywords = { - "function": 1, - "do": 1, - "then": 1, - "elseif": -1, - "end": -1, - "repeat": 1, - "until": -1 - }; - - var token = stream.getCurrentToken(); - if (!token || token.type != "keyword") - return; - - var val = token.value; - var stack = [val]; - var dir = indentKeywords[val]; - - if (!dir) - return; - - var startColumn = dir === -1 ? stream.getCurrentTokenColumn() : session.getLine(row).length; - var startRow = row; - - stream.step = dir === -1 ? stream.stepBackward : stream.stepForward; - while(token = stream.step()) { - if (token.type !== "keyword") - continue; - var level = dir * indentKeywords[token.value]; - - if (level > 0) { - stack.unshift(token.value); - } else if (level <= 0) { - stack.shift(); - if (!stack.length && token.value != "elseif") - break; - if (level === 0) - stack.unshift(token.value); - } - } - - var row = stream.getCurrentTokenRow(); - if (dir === -1) - return new Range(row, session.getLine(row).length, startRow, startColumn); - else - return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn()); - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/markdown.js b/lib/ace/mode/folding/markdown.js deleted file mode 100644 index aae7179a38a..00000000000 --- a/lib/ace/mode/folding/markdown.js +++ /dev/null @@ -1,125 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var BaseFoldMode = require("./fold_mode").FoldMode; -var Range = require("../../range").Range; - -var FoldMode = exports.FoldMode = function() {}; -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - this.foldingStartMarker = /^(?:[=-]+\s*$|#{1,6} |`{3})/; - - this.getFoldWidget = function(session, foldStyle, row) { - var line = session.getLine(row); - if (!this.foldingStartMarker.test(line)) - return ""; - - if (line[0] == "`") { - if (session.bgTokenizer.getState(row) == "start") - return "end"; - return "start"; - } - - return "start"; - }; - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var line = session.getLine(row); - var startColumn = line.length; - var maxRow = session.getLength(); - var startRow = row; - var endRow = row; - if (!line.match(this.foldingStartMarker)) - return; - - if (line[0] == "`") { - if (session.bgTokenizer.getState(row) !== "start") { - while (++row < maxRow) { - line = session.getLine(row); - if (line[0] == "`" & line.substring(0, 3) == "```") - break; - } - return new Range(startRow, startColumn, row, 0); - } else { - while (row -- > 0) { - line = session.getLine(row); - if (line[0] == "`" & line.substring(0, 3) == "```") - break; - } - return new Range(row, line.length, startRow, 0); - } - } - - var token; - function isHeading(row) { - token = session.getTokens(row)[0]; - return token && token.type.lastIndexOf(heading, 0) === 0; - } - - var heading = "markup.heading"; - function getLevel() { - var ch = token.value[0]; - if (ch == "=") return 6; - if (ch == "-") return 5; - return 7 - token.value.search(/[^#]/); - } - - if (isHeading(row)) { - var startHeadingLevel = getLevel(); - while (++row < maxRow) { - if (!isHeading(row)) - continue; - var level = getLevel(); - if (level >= startHeadingLevel) - break; - } - - endRow = row - (!token || ["=", "-"].indexOf(token.value[0]) == -1 ? 1 : 2); - - if (endRow > startRow) { - while (endRow > startRow && /^\s*$/.test(session.getLine(endRow))) - endRow--; - } - - if (endRow > startRow) { - var endColumn = session.getLine(endRow).length; - return new Range(startRow, startColumn, endRow, endColumn); - } - } - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/mixed.js b/lib/ace/mode/folding/mixed.js deleted file mode 100644 index 40d2cda8a0e..00000000000 --- a/lib/ace/mode/folding/mixed.js +++ /dev/null @@ -1,83 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var BaseFoldMode = require("./fold_mode").FoldMode; - -var FoldMode = exports.FoldMode = function(defaultMode, subModes) { - this.defaultMode = defaultMode; - this.subModes = subModes; -}; -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - - - this.$getMode = function(state) { - if (typeof state != "string") - state = state[0]; - for (var key in this.subModes) { - if (state.indexOf(key) === 0) - return this.subModes[key]; - } - return null; - }; - - this.$tryMode = function(state, session, foldStyle, row) { - var mode = this.$getMode(state); - return (mode ? mode.getFoldWidget(session, foldStyle, row) : ""); - }; - - this.getFoldWidget = function(session, foldStyle, row) { - return ( - this.$tryMode(session.getState(row-1), session, foldStyle, row) || - this.$tryMode(session.getState(row), session, foldStyle, row) || - this.defaultMode.getFoldWidget(session, foldStyle, row) - ); - }; - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var mode = this.$getMode(session.getState(row-1)); - - if (!mode || !mode.getFoldWidget(session, foldStyle, row)) - mode = this.$getMode(session.getState(row)); - - if (!mode || !mode.getFoldWidget(session, foldStyle, row)) - mode = this.defaultMode; - - return mode.getFoldWidgetRange(session, foldStyle, row); - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/pythonic.js b/lib/ace/mode/folding/pythonic.js deleted file mode 100644 index fd799e19661..00000000000 --- a/lib/ace/mode/folding/pythonic.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var BaseFoldMode = require("./fold_mode").FoldMode; - -var FoldMode = exports.FoldMode = function(markers) { - this.foldingStartMarker = new RegExp("([\\[{])(?:\\s*)$|(" + markers + ")(?:\\s*)(?:#.*)?$"); -}; -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var line = session.getLine(row); - var match = line.match(this.foldingStartMarker); - if (match) { - if (match[1]) - return this.openingBracketBlock(session, match[1], row, match.index); - if (match[2]) - return this.indentationBlock(session, row, match.index + match[2].length); - return this.indentationBlock(session, row); - } - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/pythonic_test.js b/lib/ace/mode/folding/pythonic_test.js deleted file mode 100644 index e30785b8ac9..00000000000 --- a/lib/ace/mode/folding/pythonic_test.js +++ /dev/null @@ -1,98 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") - require("amd-loader"); - -define(function(require, exports, module) { -"use strict"; - -var PythonMode = require("../python").Mode; -var EditSession = require("../../edit_session").EditSession; -var assert = require("../../test/assertions"); - -module.exports = { - - "test: bracket folding": function() { - var session = new EditSession([ - '[ ', - 'stuff', - ']', - '[ ', - '{ ', - '[ #-' - ]); - - var mode = new PythonMode(); - session.setFoldStyle("markbeginend"); - session.setMode(mode); - - assert.equal(session.getFoldWidget(0), "start"); - assert.equal(session.getFoldWidget(1), ""); - assert.equal(session.getFoldWidget(2), ""); - assert.equal(session.getFoldWidget(3), "start"); - assert.equal(session.getFoldWidget(4), "start"); - assert.equal(session.getFoldWidget(5), ""); - - assert.range(session.getFoldWidgetRange(0), 0, 1, 2, 0); - assert.equal(session.getFoldWidgetRange(3), null); - assert.equal(session.getFoldWidgetRange(5), null); - }, - - "test: indentation folding": function() { - var session = new EditSession([ - 'def a: #', - '', - ' b:', - ' c', - ' ', - ' c', - '', - ' ', - '' - ]); - - var mode = new PythonMode(); - session.setFoldStyle("markbeginend"); - session.setMode(mode); - - assert.equal(session.getFoldWidget(0), "start"); - assert.equal(session.getFoldWidget(1), ""); - assert.equal(session.getFoldWidget(2), "start"); - - assert.range(session.getFoldWidgetRange(0), 0, 6, 5, 3); - assert.range(session.getFoldWidgetRange(2), 2, 3, 5, 3); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) - require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/mode/folding/sqlserver.js b/lib/ace/mode/folding/sqlserver.js deleted file mode 100644 index b3fd4e93335..00000000000 --- a/lib/ace/mode/folding/sqlserver.js +++ /dev/null @@ -1,111 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var Range = require("../../range").Range; -var BaseFoldMode = require("./cstyle").FoldMode; - -var FoldMode = exports.FoldMode = function() {}; - -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - /** - * Inheriting cstyle folding because it handles the region comment folding - * and special block comment folding appropriately. - * - * Cstyle's getCommentRegionBlock() contains the sql comment characters '--' for end region block. - */ - - this.foldingStartMarker = /(\bCASE\b|\bBEGIN\b)|^\s*(\/\*)/i; - // this.foldingStopMarker = /(\bEND\b)|^[\s\*]*(\*\/)/i; - this.startRegionRe = /^\s*(\/\*|--)#?region\b/; - - this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { - var line = session.getLine(row); - - if (this.startRegionRe.test(line)) return this.getCommentRegionBlock(session, line, row); - - var match = line.match(this.foldingStartMarker); - if (match) { - var i = match.index; - if (match[1]) return this.getBeginEndBlock(session, row, i, match[1]); - - var range = session.getCommentFoldRange(row, i + match[0].length, 1); - if (range && !range.isMultiLine()) { - if (forceMultiline) { - range = this.getSectionRange(session, row); - } - else if (foldStyle != "all") range = null; - } - - return range; - } - - if (foldStyle === "markbegin") return; - //TODO: add support for end folding markers - return; - }; - - /** - * @returns {range} folding block for sequence that starts with 'CASE' or 'BEGIN' and ends with 'END' - * @param {string} matchSequence - the sequence of charaters that started the fold widget, which should remain visible when the fold widget is folded - */ - this.getBeginEndBlock = function(session, row, column, matchSequence) { - var start = { - row: row, - column: column + matchSequence.length - }; - var maxRow = session.getLength(); - var line; - - var depth = 1; - var re = /(\bCASE\b|\bBEGIN\b)|(\bEND\b)/i; - while (++row < maxRow) { - line = session.getLine(row); - var m = re.exec(line); - if (!m) continue; - if (m[1]) depth++; - else depth--; - - if (!depth) break; - } - var endRow = row; - if (endRow > start.row) { - return new Range(start.row, start.column, endRow, line.length); - } - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/velocity.js b/lib/ace/mode/folding/velocity.js deleted file mode 100644 index ce235b49cf7..00000000000 --- a/lib/ace/mode/folding/velocity.js +++ /dev/null @@ -1,120 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var BaseFoldMode = require("./fold_mode").FoldMode; -var Range = require("../../range").Range; - -var FoldMode = exports.FoldMode = function() {}; -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var range = this.indentationBlock(session, row); - if (range) - return range; - - var re = /\S/; - var line = session.getLine(row); - var startLevel = line.search(re); - if (startLevel == -1 || line[startLevel] != "##") - return; - - var startColumn = line.length; - var maxRow = session.getLength(); - var startRow = row; - var endRow = row; - - while (++row < maxRow) { - line = session.getLine(row); - var level = line.search(re); - - if (level == -1) - continue; - - if (line[level] != "##") - break; - - endRow = row; - } - - if (endRow > startRow) { - var endColumn = session.getLine(endRow).length; - return new Range(startRow, startColumn, endRow, endColumn); - } - }; - - // must return "" if there's no fold, to enable caching - this.getFoldWidget = function(session, foldStyle, row) { - var line = session.getLine(row); - var indent = line.search(/\S/); - var next = session.getLine(row + 1); - var prev = session.getLine(row - 1); - var prevIndent = prev.search(/\S/); - var nextIndent = next.search(/\S/); - - if (indent == -1) { - session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : ""; - return ""; - } - - // documentation comments - if (prevIndent == -1) { - if (indent == nextIndent && line[indent] == "##" && next[indent] == "##") { - session.foldWidgets[row - 1] = ""; - session.foldWidgets[row + 1] = ""; - return "start"; - } - } else if (prevIndent == indent && line[indent] == "##" && prev[indent] == "##") { - if (session.getLine(row - 2).search(/\S/) == -1) { - session.foldWidgets[row - 1] = "start"; - session.foldWidgets[row + 1] = ""; - return ""; - } - } - - if (prevIndent!= -1 && prevIndent < indent) - session.foldWidgets[row - 1] = "start"; - else - session.foldWidgets[row - 1] = ""; - - if (indent < nextIndent) - return "start"; - else - return ""; - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/xml.js b/lib/ace/mode/folding/xml.js deleted file mode 100644 index 21142b5c00e..00000000000 --- a/lib/ace/mode/folding/xml.js +++ /dev/null @@ -1,286 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var lang = require("../../lib/lang"); -var Range = require("../../range").Range; -var BaseFoldMode = require("./fold_mode").FoldMode; -var TokenIterator = require("../../token_iterator").TokenIterator; - -var FoldMode = exports.FoldMode = function(voidElements, optionalEndTags) { - BaseFoldMode.call(this); - this.voidElements = voidElements || {}; - this.optionalEndTags = oop.mixin({}, this.voidElements); - if (optionalEndTags) - oop.mixin(this.optionalEndTags, optionalEndTags); - -}; -oop.inherits(FoldMode, BaseFoldMode); - -var Tag = function() { - this.tagName = ""; - this.closing = false; - this.selfClosing = false; - this.start = {row: 0, column: 0}; - this.end = {row: 0, column: 0}; -}; - -function is(token, type) { - return token.type.lastIndexOf(type + ".xml") > -1; -} - -(function() { - - this.getFoldWidget = function(session, foldStyle, row) { - var tag = this._getFirstTagInLine(session, row); - - if (!tag) - return this.getCommentFoldWidget(session, row); - - if (tag.closing || (!tag.tagName && tag.selfClosing)) - return foldStyle == "markbeginend" ? "end" : ""; - - if (!tag.tagName || tag.selfClosing || this.voidElements.hasOwnProperty(tag.tagName.toLowerCase())) - return ""; - - if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column)) - return ""; - - return "start"; - }; - - this.getCommentFoldWidget = function(session, row) { - if (/comment/.test(session.getState(row)) && /'; - break; - } - } - return tag; - } else if (is(token, "tag-close")) { - tag.selfClosing = token.value == '/>'; - return tag; - } - tag.start.column += token.value.length; - } - - return null; - }; - - this._findEndTagInLine = function(session, row, tagName, startColumn) { - var tokens = session.getTokens(row); - var column = 0; - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - column += token.value.length; - if (column < startColumn) - continue; - if (is(token, "end-tag-open")) { - token = tokens[i + 1]; - if (token && token.value == tagName) - return true; - } - } - return false; - }; - - /* - * reads a full tag and places the iterator after the tag - */ - this._readTagForward = function(iterator) { - var token = iterator.getCurrentToken(); - if (!token) - return null; - - var tag = new Tag(); - do { - if (is(token, "tag-open")) { - tag.closing = is(token, "end-tag-open"); - tag.start.row = iterator.getCurrentTokenRow(); - tag.start.column = iterator.getCurrentTokenColumn(); - } else if (is(token, "tag-name")) { - tag.tagName = token.value; - } else if (is(token, "tag-close")) { - tag.selfClosing = token.value == "/>"; - tag.end.row = iterator.getCurrentTokenRow(); - tag.end.column = iterator.getCurrentTokenColumn() + token.value.length; - iterator.stepForward(); - return tag; - } - } while(token = iterator.stepForward()); - - return null; - }; - - this._readTagBackward = function(iterator) { - var token = iterator.getCurrentToken(); - if (!token) - return null; - - var tag = new Tag(); - do { - if (is(token, "tag-open")) { - tag.closing = is(token, "end-tag-open"); - tag.start.row = iterator.getCurrentTokenRow(); - tag.start.column = iterator.getCurrentTokenColumn(); - iterator.stepBackward(); - return tag; - } else if (is(token, "tag-name")) { - tag.tagName = token.value; - } else if (is(token, "tag-close")) { - tag.selfClosing = token.value == "/>"; - tag.end.row = iterator.getCurrentTokenRow(); - tag.end.column = iterator.getCurrentTokenColumn() + token.value.length; - } - } while(token = iterator.stepBackward()); - - return null; - }; - - this._pop = function(stack, tag) { - while (stack.length) { - - var top = stack[stack.length-1]; - if (!tag || top.tagName == tag.tagName) { - return stack.pop(); - } - else if (this.optionalEndTags.hasOwnProperty(top.tagName)) { - stack.pop(); - continue; - } else { - return null; - } - } - }; - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var firstTag = this._getFirstTagInLine(session, row); - - if (!firstTag) { - return this.getCommentFoldWidget(session, row) - && session.getCommentFoldRange(row, session.getLine(row).length); - } - - var isBackward = firstTag.closing || firstTag.selfClosing; - var stack = []; - var tag; - - if (!isBackward) { - var iterator = new TokenIterator(session, row, firstTag.start.column); - var start = { - row: row, - column: firstTag.start.column + firstTag.tagName.length + 2 - }; - if (firstTag.start.row == firstTag.end.row) - start.column = firstTag.end.column; - while (tag = this._readTagForward(iterator)) { - if (tag.selfClosing) { - if (!stack.length) { - tag.start.column += tag.tagName.length + 2; - tag.end.column -= 2; - return Range.fromPoints(tag.start, tag.end); - } else - continue; - } - - if (tag.closing) { - this._pop(stack, tag); - if (stack.length == 0) - return Range.fromPoints(start, tag.start); - } - else { - stack.push(tag); - } - } - } - else { - var iterator = new TokenIterator(session, row, firstTag.end.column); - var end = { - row: row, - column: firstTag.start.column - }; - - while (tag = this._readTagBackward(iterator)) { - if (tag.selfClosing) { - if (!stack.length) { - tag.start.column += tag.tagName.length + 2; - tag.end.column -= 2; - return Range.fromPoints(tag.start, tag.end); - } else - continue; - } - - if (!tag.closing) { - this._pop(stack, tag); - if (stack.length == 0) { - tag.start.column += tag.tagName.length + 2; - if (tag.start.row == tag.end.row && tag.start.column < tag.end.column) - tag.start.column = tag.end.column; - return Range.fromPoints(tag.start, end); - } - } - else { - stack.push(tag); - } - } - } - - }; - -}).call(FoldMode.prototype); - -}); diff --git a/lib/ace/mode/folding/xml_test.js b/lib/ace/mode/folding/xml_test.js deleted file mode 100644 index ec07cc05a11..00000000000 --- a/lib/ace/mode/folding/xml_test.js +++ /dev/null @@ -1,110 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") - require("amd-loader"); - -define(function(require, exports, module) { -"use strict"; - -var XmlMode = require("../xml").Mode; -var EditSession = require("../../edit_session").EditSession; -var assert = require("../../test/assertions"); - -module.exports = { - - "test: fold multi line self closing element": function() { - var session = new EditSession([ - '' - ]); - - var mode = new XmlMode(); - session.setFoldStyle("markbeginend"); - session.setMode(mode); - - assert.equal(session.getFoldWidget(0), "start"); - assert.equal(session.getFoldWidget(1), ""); - assert.equal(session.getFoldWidget(2), "end"); - - assert.range(session.getFoldWidgetRange(0), 0, 8, 2, 19); - assert.range(session.getFoldWidgetRange(2), 0, 8, 2, 19); - }, - - "test: fold should skip self closing elements": function() { - var session = new EditSession([ - '', - ' ', - '' - ]); - - var mode = new XmlMode(); - session.setFoldStyle("markbeginend"); - session.setMode(mode); - - assert.equal(session.getFoldWidget(0), "start"); - assert.equal(session.getFoldWidget(1), ""); - assert.equal(session.getFoldWidget(2), "end"); - - assert.range(session.getFoldWidgetRange(0), 0, 8, 2, 0); - assert.range(session.getFoldWidgetRange(2), 0, 8, 2, 0); - }, - - "test: fold should skip multi line self closing elements": function() { - var session = new EditSession([ - '', - ' ', - '' - ]); - - var mode = new XmlMode(); - session.setMode(mode); - session.setFoldStyle("markbeginend"); - - assert.equal(session.getFoldWidget(0), "start"); - assert.equal(session.getFoldWidget(1), "start"); - assert.equal(session.getFoldWidget(2), ""); - assert.equal(session.getFoldWidget(3), "end"); - assert.equal(session.getFoldWidget(4), "end"); - - assert.range(session.getFoldWidgetRange(0), 0, 8, 4, 0); - assert.range(session.getFoldWidgetRange(1), 1, 9, 3, 19); - assert.range(session.getFoldWidgetRange(3), 1, 9, 3, 19); - assert.range(session.getFoldWidgetRange(4), 0, 8, 4, 0); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) - require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/mode/forth.js b/lib/ace/mode/forth.js deleted file mode 100644 index 21f45ffdf17..00000000000 --- a/lib/ace/mode/forth.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var ForthHighlightRules = require("./forth_highlight_rules").ForthHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = ForthHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "--"; - this.blockComment = null; - this.$id = "ace/mode/forth"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/fortran.js b/lib/ace/mode/fortran.js deleted file mode 100644 index a47e35733d3..00000000000 --- a/lib/ace/mode/fortran.js +++ /dev/null @@ -1,113 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* Derived from Python rules */ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var FortranHighlightRules = require("./fortran_highlight_rules").FortranHighlightRules; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; -var Range = require("../range").Range; - -var Mode = function() { - this.HighlightRules = FortranHighlightRules; - this.foldingRules = new CStyleFoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "!"; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[:]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - var outdents = { - "return": 1, - "break": 1, - "continue": 1, - "RETURN": 1, - "BREAK": 1, - "CONTINUE": 1 - }; - - this.checkOutdent = function(state, line, input) { - if (input !== "\r\n" && input !== "\r" && input !== "\n") - return false; - - var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens; - - if (!tokens) - return false; - do { - var last = tokens.pop(); - } while (last && (last.type == "comment" || (last.type == "text" && last.value.match(/^\s+$/)))); - - if (!last) - return false; - - return (last.type == "keyword" && outdents[last.value]); - }; - - this.autoOutdent = function(state, doc, row) { - - row += 1; - var indent = this.$getIndent(doc.getLine(row)); - var tab = doc.getTabString(); - if (indent.slice(-tab.length) == tab) - doc.remove(new Range(row, indent.length-tab.length, row, indent.length)); - }; - - this.$id = "ace/mode/fortran"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); - diff --git a/lib/ace/mode/fsharp.js b/lib/ace/mode/fsharp.js deleted file mode 100644 index 6fba9e55d51..00000000000 --- a/lib/ace/mode/fsharp.js +++ /dev/null @@ -1,55 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function (require, exports, module) { - "use strict"; - - var oop = require("../lib/oop"); - var TextMode = require("./text").Mode; - var FSharpHighlightRules = require("./fsharp_highlight_rules").FSharpHighlightRules; - - var Mode = function () { - TextMode.call(this); - this.HighlightRules = FSharpHighlightRules; - }; - - oop.inherits(Mode, TextMode); - - - (function () { - this.lineCommentStart = "//"; - this.blockComment = {start: "(*", end: "*)"}; - - - this.$id = "ace/mode/fsharp"; - }).call(Mode.prototype); - - exports.Mode = Mode; -}); diff --git a/lib/ace/mode/fsharp_highlight_rules.js b/lib/ace/mode/fsharp_highlight_rules.js deleted file mode 100644 index 9291d93a418..00000000000 --- a/lib/ace/mode/fsharp_highlight_rules.js +++ /dev/null @@ -1,168 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function (require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var FSharpHighlightRules = function () { - - var keywordMapper = this.createKeywordMapper({ - "variable": "this", - "keyword": 'abstract|assert|base|begin|class|default|delegate|done|downcast|downto|elif\ -|else|exception|extern|false|finally|function|global|inherit|inline|interface|internal|lazy|match\ -|member|module|mutable|namespace|open|or|override|private|public|rec|return|return!|select|static\ -|struct|then|to|true|try|typeof|upcast|use|use!|val|void|when|while|with|yield|yield!|__SOURCE_DIRECTORY__\ -|as|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue\ -|eager|event|external|fixed|functor|include|method|mixin|object|parallel|process|protected|pure|sealed|tailcall\ -|trait|virtual|volatile|and|do|end|for|fun|if|in|let|let!|new|not|null|of|endif', - "constant": "true|false" - }, "identifier"); - - var floatNumber = "(?:(?:(?:(?:(?:(?:\\d+)?(?:\\.\\d+))|(?:(?:\\d+)\\.))|(?:\\d+))(?:[eE][+-]?\\d+))|(?:(?:(?:\\d+)?(?:\\.\\d+))|(?:(?:\\d+)\\.)))"; - - this.$rules = { - "start": [ - { - token: "variable.classes", - regex: '\\[\\<[.]*\\>\\]' - }, - { - token: "comment", - regex: '//.*$' - }, - { - token: "comment.start", - regex: /\(\*/, - push: "blockComment" - }, - { - token: "string", - regex: "'.'" - }, - { - token: "string", - regex: '"""', - next : [{ - token : "constant.language.escape", - regex : /\\./, - next : "qqstring" - }, { - token : "string", - regex : '"""', - next : "start" - }, { - defaultToken: "string" - }] - }, - { - token: "string", - regex: '"', - next : [{ - token : "constant.language.escape", - regex : /\\./, - next : "qqstring" - }, { - token : "string", - regex : '"', - next : "start" - }, { - defaultToken: "string" - }] - }, - { - token: ["verbatim.string", "string"], - regex: '(@?)(")', - stateName : "qqstring", - next : [{ - token : "constant.language.escape", - regex : '""' - }, { - token : "string", - regex : '"', - next : "start" - }, { - defaultToken: "string" - }] - }, - { - token: "constant.float", - regex: "(?:" + floatNumber + "|\\d+)[jJ]\\b" - }, - { - token: "constant.float", - regex: floatNumber - }, - { - token: "constant.integer", - regex: "(?:(?:(?:[1-9]\\d*)|(?:0))|(?:0[oO]?[0-7]+)|(?:0[xX][\\dA-Fa-f]+)|(?:0[bB][01]+))\\b" - }, - { - token: ["keyword.type", "variable"], - regex: "(type\\s)([a-zA-Z0-9_$\-]*\\b)" - }, - { - token: keywordMapper, - regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, - { - token: "keyword.operator", - regex: "\\+\\.|\\-\\.|\\*\\.|\\/\\.|#|;;|\\+|\\-|\\*|\\*\\*\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|<-|=" - }, - { - token: "paren.lpar", - regex: "[[({]" - }, - { - token: "paren.rpar", - regex: "[\\])}]" - } - ], - blockComment: [{ - regex: /\(\*/, - token: "comment.start", - push: "blockComment" - }, { - regex: /\*\)/, - token: "comment.end", - next: "pop" - }, { - defaultToken: "comment" - }] - }; - this.normalizeRules(); -}; - - -oop.inherits(FSharpHighlightRules, TextHighlightRules); - -exports.FSharpHighlightRules = FSharpHighlightRules; -}); diff --git a/lib/ace/mode/ftl.js b/lib/ace/mode/ftl.js deleted file mode 100644 index 949671c3311..00000000000 --- a/lib/ace/mode/ftl.js +++ /dev/null @@ -1,50 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var FtlHighlightRules = require("./ftl_highlight_rules").FtlHighlightRules; - -var Mode = function() { - this.HighlightRules = FtlHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.$id = "ace/mode/ftl"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/gcode.js b/lib/ace/mode/gcode.js deleted file mode 100644 index 6fa8e76646d..00000000000 --- a/lib/ace/mode/gcode.js +++ /dev/null @@ -1,52 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - "use strict"; - - var oop = require("../lib/oop"); - var TextMode = require("./text").Mode; - var GcodeHighlightRules = require("./gcode_highlight_rules").GcodeHighlightRules; - var Range = require("../range").Range; - - var Mode = function() { - this.HighlightRules = GcodeHighlightRules; - this.$behaviour = this.$defaultBehaviour; - }; - oop.inherits(Mode, TextMode); - - (function() { - this.$id = "ace/mode/gcode"; - }).call(Mode.prototype); - - exports.Mode = Mode; - -}); - diff --git a/lib/ace/mode/gcode_highlight_rules.js b/lib/ace/mode/gcode_highlight_rules.js deleted file mode 100644 index 5fe8ff26e5d..00000000000 --- a/lib/ace/mode/gcode_highlight_rules.js +++ /dev/null @@ -1,94 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - "use strict"; - - var oop = require("../lib/oop"); - var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - - var GcodeHighlightRules = function() { - - var keywords = ( - "IF|DO|WHILE|ENDWHILE|CALL|ENDIF|SUB|ENDSUB|GOTO|REPEAT|ENDREPEAT|CALL" - ); - - var builtinConstants = ( - "PI" - ); - - var builtinFunctions = ( - "ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN" - ); - var keywordMapper = this.createKeywordMapper({ - "support.function": builtinFunctions, - "keyword": keywords, - "constant.language": builtinConstants - }, "identifier", true); - - this.$rules = { - "start" : [ { - token : "comment", - regex : "\\(.*\\)" - }, { - token : "comment", // block number - regex : "([N])([0-9]+)" - }, { - token : "string", // " string - regex : "([G])([0-9]+\\.?[0-9]?)" - }, { - token : "string", // ' string - regex : "([M])([0-9]+\\.?[0-9]?)" - }, { - token : "constant.numeric", // float - regex : "([-+]?([0-9]*\\.?[0-9]+\\.?))|(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)" - }, { - token : keywordMapper, - regex : "[A-Z]" - }, { - token : "keyword.operator", - regex : "EQ|LT|GT|NE|GE|LE|OR|XOR" - }, { - token : "paren.lparen", - regex : "[\\[]" - }, { - token : "paren.rparen", - regex : "[\\]]" - }, { - token : "text", - regex : "\\s+" - } ] - }; - }; - - oop.inherits(GcodeHighlightRules, TextHighlightRules); - - exports.GcodeHighlightRules = GcodeHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/gherkin.js b/lib/ace/mode/gherkin.js deleted file mode 100644 index 33bb92d4b22..00000000000 --- a/lib/ace/mode/gherkin.js +++ /dev/null @@ -1,81 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2014, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var GherkinHighlightRules = require("./gherkin_highlight_rules").GherkinHighlightRules; - -var Mode = function() { - this.HighlightRules = GherkinHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "#"; - this.$id = "ace/mode/gherkin"; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - var space2 = " "; - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - - console.log(state); - - if(line.match("[ ]*\\|")) { - indent += "| "; - } - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - - if (state == "start") { - if (line.match("Scenario:|Feature:|Scenario Outline:|Background:")) { - indent += space2; - } else if(line.match("(Given|Then).+(:)$|Examples:")) { - indent += space2; - } else if(line.match("\\*.+")) { - indent += "* "; - } - } - - - return indent; - }; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/gherkin_highlight_rules.js b/lib/ace/mode/gherkin_highlight_rules.js deleted file mode 100644 index 86c221b43a5..00000000000 --- a/lib/ace/mode/gherkin_highlight_rules.js +++ /dev/null @@ -1,150 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2014, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var stringEscape = "\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})"; - -var GherkinHighlightRules = function() { - var languages = [{ - name: "en", - labels: "Feature|Background|Scenario(?: Outline)?|Examples", - keywords: "Given|When|Then|And|But" - } - /* TODO find a way to enable this when first line in the file is # language: pl - , { - name: "pl", - labels: "Właściwość|Funkcja|Aspekt|Potrzeba biznesowa|Założenia|Scenariusz|Szablon scenariusza|Przykłady", - keywords: "Mając|Zakładając(?:, że)?|Jeżeli|Jeśli|Gdy|Kiedy|Wtedy|Oraz|I|Ale" - } - */]; - - var labels = languages.map(function(l) { - return l.labels; - }).join("|"); - var keywords = languages.map(function(l) { - return l.keywords; - }).join("|"); - - // need to include constant ints - this.$rules = { - start : [{ - token: "constant.numeric", - regex: "(?:(?:[1-9]\\d*)|(?:0))" - }, { - token : "comment", - regex : "#.*$" - }, { - token : "keyword", - regex : "(?:" + labels + "):|(?:" + keywords + ")\\b" - }, { - token : "keyword", - regex : "\\*" - }, { - token : "string", // multi line """ string start - regex : '"{3}', - next : "qqstring3" - }, { - token : "string", // " string - regex : '"', - next : "qqstring" - }, { - token : "text", - regex : "^\\s*(?=@[\\w])", - next : [{ - token : "text", - regex : "\\s+" - }, { - token : "variable.parameter", - regex : "@[\\w]+" - }, { - token : "empty", - regex : "", - next : "start" - }] - }, { - token : "comment", - regex : "<[^>]+>" - }, { - token : "comment", - regex : "\\|(?=.)", - next : "table-item" - }, { - token : "comment", - regex : "\\|$", - next : "start" - }], - "qqstring3" : [ { - token : "constant.language.escape", - regex : stringEscape - }, { - token : "string", // multi line """ string end - regex : '"{3}', - next : "start" - }, { - defaultToken : "string" - }], - "qqstring" : [{ - token : "constant.language.escape", - regex : stringEscape - }, { - token : "string", - regex : "\\\\$", - next : "qqstring" - }, { - token : "string", - regex : '"|$', - next : "start" - }, { - defaultToken: "string" - }], - "table-item" : [{ - token : "comment", - regex : /$/, - next : "start" - }, { - token : "comment", - regex : /\|/ - }, { - token : "string", - regex : /\\./ - }, { - defaultToken : "string" - }] - }; - this.normalizeRules(); -}; - -oop.inherits(GherkinHighlightRules, TextHighlightRules); - -exports.GherkinHighlightRules = GherkinHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/gitignore.js b/lib/ace/mode/gitignore.js deleted file mode 100644 index 17c03a9d1c8..00000000000 --- a/lib/ace/mode/gitignore.js +++ /dev/null @@ -1,21 +0,0 @@ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var GitignoreHighlightRules = require("./gitignore_highlight_rules").GitignoreHighlightRules; - -var Mode = function() { - this.HighlightRules = GitignoreHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "#"; - this.$id = "ace/mode/gitignore"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/glsl.js b/lib/ace/mode/glsl.js deleted file mode 100644 index dab631066ac..00000000000 --- a/lib/ace/mode/glsl.js +++ /dev/null @@ -1,56 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var CMode = require("./c_cpp").Mode; -var glslHighlightRules = require("./glsl_highlight_rules").glslHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = glslHighlightRules; - - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, CMode); - -(function() { - this.$id = "ace/mode/glsl"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/glsl_highlight_rules.js b/lib/ace/mode/glsl_highlight_rules.js deleted file mode 100644 index 22218fbe0c9..00000000000 --- a/lib/ace/mode/glsl_highlight_rules.js +++ /dev/null @@ -1,81 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var c_cppHighlightRules = require("./c_cpp_highlight_rules").c_cppHighlightRules; - -var glslHighlightRules = function() { - - var keywords = ( - "attribute|const|uniform|varying|break|continue|do|for|while|" + - "if|else|in|out|inout|float|int|void|bool|true|false|" + - "lowp|mediump|highp|precision|invariant|discard|return|mat2|mat3|" + - "mat4|vec2|vec3|vec4|ivec2|ivec3|ivec4|bvec2|bvec3|bvec4|sampler2D|" + - "samplerCube|struct" - ); - - var buildinConstants = ( - "radians|degrees|sin|cos|tan|asin|acos|atan|pow|" + - "exp|log|exp2|log2|sqrt|inversesqrt|abs|sign|floor|ceil|fract|mod|" + - "min|max|clamp|mix|step|smoothstep|length|distance|dot|cross|" + - "normalize|faceforward|reflect|refract|matrixCompMult|lessThan|" + - "lessThanEqual|greaterThan|greaterThanEqual|equal|notEqual|any|all|" + - "not|dFdx|dFdy|fwidth|texture2D|texture2DProj|texture2DLod|" + - "texture2DProjLod|textureCube|textureCubeLod|" + - "gl_MaxVertexAttribs|gl_MaxVertexUniformVectors|gl_MaxVaryingVectors|" + - "gl_MaxVertexTextureImageUnits|gl_MaxCombinedTextureImageUnits|" + - "gl_MaxTextureImageUnits|gl_MaxFragmentUniformVectors|gl_MaxDrawBuffers|" + - "gl_DepthRangeParameters|gl_DepthRange|" + - // The following two are only for MIME x-shader/x-vertex. - "gl_Position|gl_PointSize|" + - // The following five are only for MIME x-shader/x-fragment. - "gl_FragCoord|gl_FrontFacing|gl_PointCoord|gl_FragColor|gl_FragData" - ); - - var keywordMapper = this.createKeywordMapper({ - "variable.language": "this", - "keyword": keywords, - "constant.language": buildinConstants - }, "identifier"); - - this.$rules = new c_cppHighlightRules().$rules; - this.$rules.start.forEach(function(rule) { - if (typeof rule.token == "function") - rule.token = keywordMapper; - }); -}; - -oop.inherits(glslHighlightRules, c_cppHighlightRules); - -exports.glslHighlightRules = glslHighlightRules; -}); diff --git a/lib/ace/mode/gobstones.js b/lib/ace/mode/gobstones.js deleted file mode 100644 index f4fd08d6692..00000000000 --- a/lib/ace/mode/gobstones.js +++ /dev/null @@ -1,26 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var JavaScriptMode = require("./javascript").Mode; -var GobstonesHighlightRules = require("./gobstones_highlight_rules").GobstonesHighlightRules; - -var Mode = function() { - JavaScriptMode.call(this); - this.HighlightRules = GobstonesHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, JavaScriptMode); - -(function() { - - this.createWorker = function(session) { - return null; - }; - - this.$id = "ace/mode/gobstones"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); - diff --git a/lib/ace/mode/gobstones_highlight_rules.js b/lib/ace/mode/gobstones_highlight_rules.js deleted file mode 100644 index 5ccbf161c73..00000000000 --- a/lib/ace/mode/gobstones_highlight_rules.js +++ /dev/null @@ -1,111 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var GobstonesHighlightRules = function() { - - var keywords = ( - "program|procedure|function|interactive|if|then|else|switch|repeat|while|foreach|in|not|div|mod|Skip|return" - ); - - var buildinConstants = ( - "False|True" - ); - - - var langClasses = ( - "Poner|Sacar|Mover|IrAlBorde|VaciarTablero|" + - "nroBolitas|hayBolitas|puedeMover|siguiente|previo|opuesto|minBool|maxBool|" + - "minDir|maxDir|minColor|maxColor" - ); - - var supportType = ( - "Verde|Rojo|Azul|Negro|Norte|Sur|Este|Oeste" - ); - - var keywordMapper = this.createKeywordMapper({ - "keyword": keywords, - "constant.language": buildinConstants, - "support.function": langClasses, - "support.type": supportType - }, "identifier"); - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { - "start" : [ - { - token : "comment", - regex : "\\/\\/.*$" - }, - { - token : "comment", - regex : "\\-\\-.*$" - }, - { - token : "comment", - regex : "#.*$" - }, - DocCommentHighlightRules.getStartRule("doc-start"), - { - token : "comment", // multi line comment - regex : "\\/\\*", - next : "comment" - }, { - - token : "string", // single line - regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - }, { - token : "string", // single line - regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, { - token : "constant.numeric", // hex - regex : /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\b/ - }, { - token : "constant.numeric", // float - regex : /[+-]?\d[\d_]*(?:(?:\.[\d_]*)?(?:[eE][+-]?[\d_]+)?)?[LlSsDdFfYy]?\b/ - }, { - token : "constant.language.boolean", - regex : "(?:True|False)\\b" - }, { - token : "keyword.operator", - regex : ":=|\\.\\.|,|;|\\|\\||\\/\\/|\\+|\\-|\\^|\\*|>|<|>=|=>|==|&&" - }, { - token : keywordMapper, - // TODO: Unicode escape sequences - // TODO: Unicode identifiers - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "lparen", - regex : "[[({]" - }, { - token : "rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" - } - ], - "comment" : [ - { - token : "comment", // closing comment - regex : "\\*\\/", - next : "start" - }, { - defaultToken : "comment" - } - ] - }; - - this.embedRules(DocCommentHighlightRules, "doc-", - [ DocCommentHighlightRules.getEndRule("start") ]); -}; - -oop.inherits(GobstonesHighlightRules, TextHighlightRules); - -exports.GobstonesHighlightRules = GobstonesHighlightRules; -}); diff --git a/lib/ace/mode/golang.js b/lib/ace/mode/golang.js deleted file mode 100644 index 012ae5bed8c..00000000000 --- a/lib/ace/mode/golang.js +++ /dev/null @@ -1,56 +0,0 @@ -define(function(require, exports, module) { - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var GolangHighlightRules = require("./golang_highlight_rules").GolangHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = GolangHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.foldingRules = new CStyleFoldMode(); - this.$behaviour = new CstyleBehaviour(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - };//end getNextLineIndent - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/golang"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/graphqlschema.js b/lib/ace/mode/graphqlschema.js deleted file mode 100644 index a23fd32df14..00000000000 --- a/lib/ace/mode/graphqlschema.js +++ /dev/null @@ -1,51 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var GraphQLSchemaHighlightRules = require("./graphqlschema_highlight_rules").GraphQLSchemaHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = GraphQLSchemaHighlightRules; - this.foldingRules = new FoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "#"; - this.$id = "ace/mode/graphqlschema"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/graphqlschema_highlight_rules.js b/lib/ace/mode/graphqlschema_highlight_rules.js deleted file mode 100644 index 4cb095d8bc8..00000000000 --- a/lib/ace/mode/graphqlschema_highlight_rules.js +++ /dev/null @@ -1,74 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var GraphQLSchemaHighlightRules = function() { - - var keywords = ( - "type|interface|union|enum|schema|input|implements|extends|scalar" - ); - - var dataTypes = ( - "Int|Float|String|ID|Boolean" - ); - - var keywordMapper = this.createKeywordMapper({ - "keyword": keywords, - "storage.type": dataTypes - }, "identifier"); - - this.$rules = { - "start" : [ { - token : "comment", - regex : "#.*$" - }, { - token : "paren.lparen", - regex : /[\[({]/, - next : "start" - }, { - token : "paren.rparen", - regex : /[\])}]/ - }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - } ] - }; - this.normalizeRules(); -}; - -oop.inherits(GraphQLSchemaHighlightRules, TextHighlightRules); - -exports.GraphQLSchemaHighlightRules = GraphQLSchemaHighlightRules; -}); diff --git a/lib/ace/mode/groovy.js b/lib/ace/mode/groovy.js deleted file mode 100644 index 107998bf8a2..00000000000 --- a/lib/ace/mode/groovy.js +++ /dev/null @@ -1,24 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var JavaScriptMode = require("./javascript").Mode; -var GroovyHighlightRules = require("./groovy_highlight_rules").GroovyHighlightRules; - -var Mode = function() { - JavaScriptMode.call(this); - this.HighlightRules = GroovyHighlightRules; -}; -oop.inherits(Mode, JavaScriptMode); - -(function() { - - this.createWorker = function(session) { - return null; - }; - - this.$id = "ace/mode/groovy"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/haml.js b/lib/ace/mode/haml.js deleted file mode 100644 index bce4e1e9b67..00000000000 --- a/lib/ace/mode/haml.js +++ /dev/null @@ -1,62 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * Garen J. Torikian < gjtorikian AT gmail DOT com > - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var HamlHighlightRules = require("./haml_highlight_rules").HamlHighlightRules; -var FoldMode = require("./folding/coffee").FoldMode; - -var Mode = function() { - this.HighlightRules = HamlHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - - this.$id = "ace/mode/haml"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/handlebars.js b/lib/ace/mode/handlebars.js deleted file mode 100644 index b29666ed7be..00000000000 --- a/lib/ace/mode/handlebars.js +++ /dev/null @@ -1,26 +0,0 @@ -/* global define */ - -define(function(require, exports, module) { - "use strict"; - -var oop = require("../lib/oop"); -var HtmlMode = require("./html").Mode; -var HandlebarsHighlightRules = require("./handlebars_highlight_rules").HandlebarsHighlightRules; -var HtmlBehaviour = require("./behaviour/html").HtmlBehaviour; -var HtmlFoldMode = require("./folding/html").FoldMode; - -var Mode = function() { - HtmlMode.call(this); - this.HighlightRules = HandlebarsHighlightRules; - this.$behaviour = new HtmlBehaviour(); -}; - -oop.inherits(Mode, HtmlMode); - -(function() { - this.blockComment = {start: "{{!--", end: "--}}"}; - this.$id = "ace/mode/handlebars"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/haskell.js b/lib/ace/mode/haskell.js deleted file mode 100644 index 1a06441734b..00000000000 --- a/lib/ace/mode/haskell.js +++ /dev/null @@ -1,63 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var HaskellHighlightRules = require("./haskell_highlight_rules").HaskellHighlightRules; -// TODO: pick appropriate fold mode -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = HaskellHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "--"; - this.blockComment = null; - this.$id = "ace/mode/haskell"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/haskell_cabal.js b/lib/ace/mode/haskell_cabal.js deleted file mode 100644 index 2e2880c723c..00000000000 --- a/lib/ace/mode/haskell_cabal.js +++ /dev/null @@ -1,61 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * - * - * ***** END LICENSE BLOCK ***** */ -/** -* Haskell Cabal files mode (https://www.haskell.org/cabal/users-guide/developing-packages.html) -**/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var CabalHighlightRules = require("./haskell_cabal_highlight_rules").CabalHighlightRules; -var FoldMode = require("./folding/haskell_cabal").FoldMode; - -var Mode = function() { - this.HighlightRules = CabalHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "--"; - this.blockComment = null; - this.$id = "ace/mode/haskell_cabal"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/haskell_cabal_highlight_rules.js b/lib/ace/mode/haskell_cabal_highlight_rules.js deleted file mode 100644 index 673aeade989..00000000000 --- a/lib/ace/mode/haskell_cabal_highlight_rules.js +++ /dev/null @@ -1,68 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - /** - * Haskell Cabal files highlighter (https://www.haskell.org/cabal/users-guide/developing-packages.html) - **/ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var CabalHighlightRules = function() { - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - this.$rules = { - "start" : [ - { - token : "comment", - regex : "^\\s*--.*$" - }, { - token: ["keyword"], - regex: /^(\s*\w.*?)(:(?:\s+|$))/ - }, { - token : "constant.numeric", // float - regex : /[\d_]+(?:(?:[\.\d_]*)?)/ - }, { - token : "constant.language.boolean", - regex : "(?:true|false|TRUE|FALSE|True|False|yes|no)\\b" - }, { - token : "markup.heading", - regex : /^(\w.*)$/ - } - ]}; - -}; - -oop.inherits(CabalHighlightRules, TextHighlightRules); - -exports.CabalHighlightRules = CabalHighlightRules; -}); diff --git a/lib/ace/mode/haxe.js b/lib/ace/mode/haxe.js deleted file mode 100644 index e2ac5a26b7a..00000000000 --- a/lib/ace/mode/haxe.js +++ /dev/null @@ -1,56 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var HaxeHighlightRules = require("./haxe_highlight_rules").HaxeHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = HaxeHighlightRules; - - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/haxe"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/hjson.js b/lib/ace/mode/hjson.js deleted file mode 100644 index 72aac0a101c..00000000000 --- a/lib/ace/mode/hjson.js +++ /dev/null @@ -1,52 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var HjsonHighlightRules = require("./hjson_highlight_rules").HjsonHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = HjsonHighlightRules; - this.foldingRules = new FoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.blockComment = { start: "/*", end: "*/" }; - this.$id = "ace/mode/hjson"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/html.js b/lib/ace/mode/html.js deleted file mode 100644 index a74ee3ded0f..00000000000 --- a/lib/ace/mode/html.js +++ /dev/null @@ -1,106 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var TextMode = require("./text").Mode; -var JavaScriptMode = require("./javascript").Mode; -var CssMode = require("./css").Mode; -var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; -var XmlBehaviour = require("./behaviour/xml").XmlBehaviour; -var HtmlFoldMode = require("./folding/html").FoldMode; -var HtmlCompletions = require("./html_completions").HtmlCompletions; -var WorkerClient = require("../worker/worker_client").WorkerClient; - -// http://www.w3.org/TR/html5/syntax.html#void-elements -var voidElements = ["area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "meta", "menuitem", "param", "source", "track", "wbr"]; -var optionalEndTags = ["li", "dt", "dd", "p", "rt", "rp", "optgroup", "option", "colgroup", "td", "th"]; - -var Mode = function(options) { - this.fragmentContext = options && options.fragmentContext; - this.HighlightRules = HtmlHighlightRules; - this.$behaviour = new XmlBehaviour(); - this.$completer = new HtmlCompletions(); - - this.createModeDelegates({ - "js-": JavaScriptMode, - "css-": CssMode - }); - - this.foldingRules = new HtmlFoldMode(this.voidElements, lang.arrayToMap(optionalEndTags)); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.blockComment = {start: ""}; - - this.voidElements = lang.arrayToMap(voidElements); - - this.getNextLineIndent = function(state, line, tab) { - return this.$getIndent(line); - }; - - this.checkOutdent = function(state, line, input) { - return false; - }; - - this.getCompletions = function(state, session, pos, prefix) { - return this.$completer.getCompletions(state, session, pos, prefix); - }; - - this.createWorker = function(session) { - if (this.constructor != Mode) - return; - var worker = new WorkerClient(["ace"], "ace/mode/html_worker", "Worker"); - worker.attachToDocument(session.getDocument()); - - if (this.fragmentContext) - worker.call("setOptions", [{context: this.fragmentContext}]); - - worker.on("error", function(e) { - session.setAnnotations(e.data); - }); - - worker.on("terminate", function() { - session.clearAnnotations(); - }); - - return worker; - }; - - this.$id = "ace/mode/html"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/html/saxparser.js b/lib/ace/mode/html/saxparser.js index e19e1fc4749..fb4d1123da4 100644 --- a/lib/ace/mode/html/saxparser.js +++ b/lib/ace/mode/html/saxparser.js @@ -4949,7 +4949,9 @@ TreeBuilder.prototype.startTokenization = function(tokenizer) { this.openElements = new ElementStack(); this.activeFormattingElements = []; this.start(); - if (this.context) { + if (this.context) { + // This means user want to setup an HTML fragment + switch(this.context) { case 'title': case 'textarea': @@ -4973,7 +4975,16 @@ TreeBuilder.prototype.startTokenization = function(tokenizer) { this.tokenizer.setState(Tokenizer.PLAINTEXT); break; } - this.insertHtmlElement(); + this.insertHtmlElement(); + + if (this.context === 'head') { + // In case it's an 'head' fragment, we insert a head DOM element + this.insertHeadElement(); + } else { + // Else a body DOM element + this.insertBodyElement(); + } + this.resetInsertionMode(); // todo form pointer } else { @@ -5320,13 +5331,14 @@ TreeBuilder.prototype.parseError = function(code, args) { * Resets the insertion mode (http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#reset-the-insertion-mode-appropriately) */ TreeBuilder.prototype.resetInsertionMode = function() { - var last = false; + var fragmentAssigned = false; var node = null; for (var i = this.openElements.length - 1; i >= 0; i--) { node = this.openElements.item(i); - if (i === 0) { + if (i === 0) { + // Normally we enter here if a fragment context has been set assert.ok(this.context); - last = true; + fragmentAssigned = true; node = new StackItem("http://www.w3.org/1999/xhtml", this.context, [], null); } @@ -5347,7 +5359,7 @@ TreeBuilder.prototype.resetInsertionMode = function() { return this.setInsertionMode('inColumnGroup'); if (node.localName === 'table') return this.setInsertionMode('inTable'); - if (node.localName === 'head' && !last) + if (node.localName === 'head') return this.setInsertionMode('inHead'); if (node.localName === 'body') return this.setInsertionMode('inBody'); @@ -5360,7 +5372,7 @@ TreeBuilder.prototype.resetInsertionMode = function() { return this.setInsertionMode('afterHead'); } - if (last) + if (fragmentAssigned) return this.setInsertionMode('inBody'); } }; @@ -5823,7 +5835,10 @@ function SAXParser() { this._scriptingEnabled = false; } -SAXParser.prototype.parse = function(source) { +SAXParser.prototype.parse = function(source, context) { + if (context) { + this._treeBuilder.setFragmentContext(context); + } this._tokenizer.tokenize(source); var document = this._treeBuilder.document; if (document) { diff --git a/lib/ace/mode/html_elixir.js b/lib/ace/mode/html_elixir.js deleted file mode 100644 index 079399b8b9a..00000000000 --- a/lib/ace/mode/html_elixir.js +++ /dev/null @@ -1,59 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var HtmlElixirHighlightRules = require("./html_elixir_highlight_rules").HtmlElixirHighlightRules; -var HtmlMode = require("./html").Mode; -var JavaScriptMode = require("./javascript").Mode; -var CssMode = require("./css").Mode; -var ElixirMode = require("./elixir").Mode; - -var Mode = function() { - HtmlMode.call(this); - this.HighlightRules = HtmlElixirHighlightRules; - this.createModeDelegates({ - "js-": JavaScriptMode, - "css-": CssMode, - "elixir-": ElixirMode - }); -}; -oop.inherits(Mode, HtmlMode); - -(function() { - - this.$id = "ace/mode/html_elixir"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/html_elixir_highlight_rules.js b/lib/ace/mode/html_elixir_highlight_rules.js deleted file mode 100644 index 9d61ea107e1..00000000000 --- a/lib/ace/mode/html_elixir_highlight_rules.js +++ /dev/null @@ -1,84 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - "use strict"; - - var oop = require("../lib/oop"); - var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; - var ElixirHighlightRules = require("./elixir_highlight_rules").ElixirHighlightRules; - - var HtmlElixirHighlightRules = function() { - HtmlHighlightRules.call(this); - - var startRules = [ - { - regex: "<%%|%%>", - token: "constant.language.escape" - }, { - token : "comment.start.eex", - regex : "<%#", - push : [{ - token : "comment.end.eex", - regex: "%>", - next: "pop", - defaultToken:"comment" - }] - }, { - token : "support.elixir_tag", - regex : "<%+(?!>)[-=]?", - push : "elixir-start" - } - ]; - - var endRules = [ - { - token : "support.elixir_tag", - regex : "%>", - next : "pop" - }, { - token: "comment", - regex: "#(?:[^%]|%[^>])*" - } - ]; - - for (var key in this.$rules) - this.$rules[key].unshift.apply(this.$rules[key], startRules); - - this.embedRules(ElixirHighlightRules, "elixir-", endRules, ["start"]); - - this.normalizeRules(); - }; - - - oop.inherits(HtmlElixirHighlightRules, HtmlHighlightRules); - - exports.HtmlElixirHighlightRules = HtmlElixirHighlightRules; -}); diff --git a/lib/ace/mode/html_highlight_rules.js b/lib/ace/mode/html_highlight_rules.js deleted file mode 100644 index de8661b16c5..00000000000 --- a/lib/ace/mode/html_highlight_rules.js +++ /dev/null @@ -1,111 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; -var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; -var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules; - -var tagMap = lang.createMap({ - a : 'anchor', - button : 'form', - form : 'form', - img : 'image', - input : 'form', - label : 'form', - option : 'form', - script : 'script', - select : 'form', - textarea : 'form', - style : 'style', - table : 'table', - tbody : 'table', - td : 'table', - tfoot : 'table', - th : 'table', - tr : 'table' -}); - -var HtmlHighlightRules = function() { - XmlHighlightRules.call(this); - - this.addRules({ - attributes: [{ - include : "tag_whitespace" - }, { - token : "entity.other.attribute-name.xml", - regex : "[-_a-zA-Z0-9:.]+" - }, { - token : "keyword.operator.attribute-equals.xml", - regex : "=", - push : [{ - include: "tag_whitespace" - }, { - token : "string.unquoted.attribute-value.html", - regex : "[^<>='\"`\\s]+", - next : "pop" - }, { - token : "empty", - regex : "", - next : "pop" - }] - }, { - include : "attribute_value" - }], - tag: [{ - token : function(start, tag) { - var group = tagMap[tag]; - return ["meta.tag.punctuation." + (start == "<" ? "" : "end-") + "tag-open.xml", - "meta.tag" + (group ? "." + group : "") + ".tag-name.xml"]; - }, - regex : "(", next : "start"} - ] - }); - - this.embedTagRules(CssHighlightRules, "css-", "style"); - this.embedTagRules(new JavaScriptHighlightRules({jsx: false}).getRules(), "js-", "script"); - - if (this.constructor === HtmlHighlightRules) - this.normalizeRules(); -}; - -oop.inherits(HtmlHighlightRules, XmlHighlightRules); - -exports.HtmlHighlightRules = HtmlHighlightRules; -}); diff --git a/lib/ace/mode/html_ruby.js b/lib/ace/mode/html_ruby.js deleted file mode 100644 index ab9aa083404..00000000000 --- a/lib/ace/mode/html_ruby.js +++ /dev/null @@ -1,59 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var HtmlRubyHighlightRules = require("./html_ruby_highlight_rules").HtmlRubyHighlightRules; -var HtmlMode = require("./html").Mode; -var JavaScriptMode = require("./javascript").Mode; -var CssMode = require("./css").Mode; -var RubyMode = require("./ruby").Mode; - -var Mode = function() { - HtmlMode.call(this); - this.HighlightRules = HtmlRubyHighlightRules; - this.createModeDelegates({ - "js-": JavaScriptMode, - "css-": CssMode, - "ruby-": RubyMode - }); -}; -oop.inherits(Mode, HtmlMode); - -(function() { - - this.$id = "ace/mode/html_ruby"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/html_ruby_highlight_rules.js b/lib/ace/mode/html_ruby_highlight_rules.js deleted file mode 100644 index 47f113cfc67..00000000000 --- a/lib/ace/mode/html_ruby_highlight_rules.js +++ /dev/null @@ -1,84 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - "use strict"; - - var oop = require("../lib/oop"); - var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; - var RubyHighlightRules = require("./ruby_highlight_rules").RubyHighlightRules; - - var HtmlRubyHighlightRules = function() { - HtmlHighlightRules.call(this); - - var startRules = [ - { - regex: "<%%|%%>", - token: "constant.language.escape" - }, { - token : "comment.start.erb", - regex : "<%#", - push : [{ - token : "comment.end.erb", - regex: "%>", - next: "pop", - defaultToken:"comment" - }] - }, { - token : "support.ruby_tag", - regex : "<%+(?!>)[-=]?", - push : "ruby-start" - } - ]; - - var endRules = [ - { - token : "support.ruby_tag", - regex : "%>", - next : "pop" - }, { - token: "comment", - regex: "#(?:[^%]|%[^>])*" - } - ]; - - for (var key in this.$rules) - this.$rules[key].unshift.apply(this.$rules[key], startRules); - - this.embedRules(RubyHighlightRules, "ruby-", endRules, ["start"]); - - this.normalizeRules(); - }; - - - oop.inherits(HtmlRubyHighlightRules, HtmlHighlightRules); - - exports.HtmlRubyHighlightRules = HtmlRubyHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/html_test.js b/lib/ace/mode/html_test.js deleted file mode 100644 index 10f3fea4294..00000000000 --- a/lib/ace/mode/html_test.js +++ /dev/null @@ -1,67 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") { - require("amd-loader"); -} - -define(function(require, exports, module) { -"use strict"; - -var EditSession = require("../edit_session").EditSession; -var Range = require("../range").Range; -var HtmlMode = require("./html").Mode; -var assert = require("../test/assertions"); - -module.exports = { - setUp : function() { - this.mode = new HtmlMode(); - }, - - "test: toggle comment lines" : function() { - var session = new EditSession([" abc", "", "fg"]); - - var range = new Range(0, 3, 1, 1); - var comment = this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal([" ", "", "fg"].join("\n"), session.toString()); - }, - - "test: next line indent should be the same as the current line indent" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " abc")); - assert.equal("", this.mode.getNextLineIndent("start", "abc")); - assert.equal("\t", this.mode.getNextLineIndent("start", "\tabc")); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/mode/html_worker.js b/lib/ace/mode/html_worker.js index ec595f31972..150993f03eb 100644 --- a/lib/ace/mode/html_worker.js +++ b/lib/ace/mode/html_worker.js @@ -45,6 +45,11 @@ var errorTypes = { var Worker = exports.Worker = function(sender) { Mirror.call(this, sender); this.setTimeout(400); + + // The context is currently only used for Fragment + // It's format is an object: {fragmentContext: "body"} + // %Value% need to be a string of a DOM Element type: + // "head" | "body" | "footer" | ... this.context = null; }; @@ -80,10 +85,9 @@ oop.inherits(Worker, Mirror); }); } }; - if (this.context) - parser.parseFragment(value, this.context); - else - parser.parse(value); + + parser.parse(value, this.context); + this.sender.emit("error", errors); }; diff --git a/lib/ace/mode/ini.js b/lib/ace/mode/ini.js deleted file mode 100644 index 9a07397a69b..00000000000 --- a/lib/ace/mode/ini.js +++ /dev/null @@ -1,54 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var IniHighlightRules = require("./ini_highlight_rules").IniHighlightRules; -// TODO: pick appropriate fold mode -var FoldMode = require("./folding/ini").FoldMode; - -var Mode = function() { - this.HighlightRules = IniHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = ";"; - this.blockComment = null; - this.$id = "ace/mode/ini"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/ini_highlight_rules.js b/lib/ace/mode/ini_highlight_rules.js deleted file mode 100644 index 8ce3d949f42..00000000000 --- a/lib/ace/mode/ini_highlight_rules.js +++ /dev/null @@ -1,112 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* This file was autogenerated from tool\tm bundles\ini.tmbundle\Syntaxes\Ini.plist (uuid: ) */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var escapeRe = "\\\\(?:[\\\\0abtrn;#=:]|x[a-fA-F\\d]{4})"; - -var IniHighlightRules = function() { - this.$rules = { - start: [{ - token: 'punctuation.definition.comment.ini', - regex: '#.*', - push_: [{ - token: 'comment.line.number-sign.ini', - regex: '$|^', - next: 'pop' - }, { - defaultToken: 'comment.line.number-sign.ini' - }] - }, { - token: 'punctuation.definition.comment.ini', - regex: ';.*', - push_: [{ - token: 'comment.line.semicolon.ini', - regex: '$|^', - next: 'pop' - }, { - defaultToken: 'comment.line.semicolon.ini' - }] - }, { - token: ['keyword.other.definition.ini', 'text', 'punctuation.separator.key-value.ini'], - regex: '\\b([a-zA-Z0-9_.-]+)\\b(\\s*)(=)' - }, { - token: ['punctuation.definition.entity.ini', 'constant.section.group-title.ini', 'punctuation.definition.entity.ini'], - regex: '^(\\[)(.*?)(\\])' - }, { - token: 'punctuation.definition.string.begin.ini', - regex: "'", - push: [{ - token: 'punctuation.definition.string.end.ini', - regex: "'", - next: 'pop' - }, { - token: "constant.language.escape", - regex: escapeRe - }, { - defaultToken: 'string.quoted.single.ini' - }] - }, { - token: 'punctuation.definition.string.begin.ini', - regex: '"', - push: [{ - token: "constant.language.escape", - regex: escapeRe - }, { - token: 'punctuation.definition.string.end.ini', - regex: '"', - next: 'pop' - }, { - defaultToken: 'string.quoted.double.ini' - }] - }] - }; - - this.normalizeRules(); -}; - -IniHighlightRules.metaData = { - fileTypes: ['ini', 'conf'], - keyEquivalent: '^~I', - name: 'Ini', - scopeName: 'source.ini' -}; - - -oop.inherits(IniHighlightRules, TextHighlightRules); - -exports.IniHighlightRules = IniHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/io.js b/lib/ace/mode/io.js deleted file mode 100644 index fd1ecf85ddf..00000000000 --- a/lib/ace/mode/io.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var IoHighlightRules = require("./io_highlight_rules").IoHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = IoHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - // Extra logic goes here. - this.$id = "ace/mode/io"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/io_highlight_rules.js b/lib/ace/mode/io_highlight_rules.js deleted file mode 100644 index 34f3fb9383b..00000000000 --- a/lib/ace/mode/io_highlight_rules.js +++ /dev/null @@ -1,120 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* This file was autogenerated from tm bundles\io.tmbundle/Syntaxes/io.plist (uuid: ) */ -/**************************************************************************************** - * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * - * fileTypes * - ****************************************************************************************/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var IoHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { start: - [ { token: [ 'text', 'meta.empty-parenthesis.io' ], - regex: '(\\()(\\))', - comment: 'we match this to overload return inside () --Allan; scoping rules for what gets the scope have changed, so we now group the ) instead of the ( -- Rob' }, - { token: [ 'text', 'meta.comma-parenthesis.io' ], - regex: '(\\,)(\\))', - comment: 'We want to do the same for ,) -- Seckar; same as above -- Rob' }, - { token: 'keyword.control.io', - regex: '\\b(?:if|ifTrue|ifFalse|ifTrueIfFalse|for|loop|reverseForeach|foreach|map|continue|break|while|do|return)\\b' }, - { token: 'punctuation.definition.comment.io', - regex: '/\\*', - push: - [ { token: 'punctuation.definition.comment.io', - regex: '\\*/', - next: 'pop' }, - { defaultToken: 'comment.block.io' } ] }, - { token: 'punctuation.definition.comment.io', - regex: '//', - push: - [ { token: 'comment.line.double-slash.io', - regex: '$', - next: 'pop' }, - { defaultToken: 'comment.line.double-slash.io' } ] }, - { token: 'punctuation.definition.comment.io', - regex: '#', - push: - [ { token: 'comment.line.number-sign.io', regex: '$', next: 'pop' }, - { defaultToken: 'comment.line.number-sign.io' } ] }, - { token: 'variable.language.io', - regex: '\\b(?:self|sender|target|proto|protos|parent)\\b', - 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' }, - { token: 'keyword.operator.io', - regex: '<=|>=|=|:=|\\*|\\||\\|\\||\\+|-|/|&|&&|>|<|\\?|@|@@|\\b(?:and|or)\\b' }, - { token: 'constant.other.io', regex: '\\bGL[\\w_]+\\b' }, - { token: 'support.class.io', regex: '\\b[A-Z](?:\\w+)?\\b' }, - { token: 'support.function.io', - regex: '\\b(?:clone|call|init|method|list|vector|block|\\w+(?=\\s*\\())\\b' }, - { token: 'support.function.open-gl.io', - regex: '\\bgl(?:u|ut)?[A-Z]\\w+\\b' }, - { token: 'punctuation.definition.string.begin.io', - regex: '"""', - push: - [ { token: 'punctuation.definition.string.end.io', - regex: '"""', - next: 'pop' }, - { token: 'constant.character.escape.io', regex: '\\\\.' }, - { defaultToken: 'string.quoted.triple.io' } ] }, - { token: 'punctuation.definition.string.begin.io', - regex: '"', - push: - [ { token: 'punctuation.definition.string.end.io', - regex: '"', - next: 'pop' }, - { token: 'constant.character.escape.io', regex: '\\\\.' }, - { defaultToken: 'string.quoted.double.io' } ] }, - { token: 'constant.numeric.io', - 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' }, - { token: 'variable.other.global.io', regex: 'Lobby\\b' }, - { token: 'constant.language.io', - regex: '\\b(?:TRUE|true|FALSE|false|NULL|null|Null|Nil|nil|YES|NO)\\b' } ] }; - - this.normalizeRules(); -}; - -IoHighlightRules.metaData = { fileTypes: [ 'io' ], - keyEquivalent: '^~I', - name: 'Io', - scopeName: 'source.io' }; - - -oop.inherits(IoHighlightRules, TextHighlightRules); - -exports.IoHighlightRules = IoHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/jack.js b/lib/ace/mode/jack.js deleted file mode 100644 index 73267c4b503..00000000000 --- a/lib/ace/mode/jack.js +++ /dev/null @@ -1,79 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var HighlightRules = require("./jack_highlight_rules").JackHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = HighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "--"; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - - this.$id = "ace/mode/jack"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/jack_highlight_rules.js b/lib/ace/mode/jack_highlight_rules.js deleted file mode 100644 index edf7c856abf..00000000000 --- a/lib/ace/mode/jack_highlight_rules.js +++ /dev/null @@ -1,142 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var JackHighlightRules = function() { - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - this.$rules = { - "start" : [ - { - token : "string", - regex : '"', - next : "string2" - }, { - token : "string", - regex : "'", - next : "string1" - }, { - token : "constant.numeric", // hex - regex: "-?0[xX][0-9a-fA-F]+\\b" - }, { - token : "constant.numeric", // float - regex : "(?:0|[-+]?[1-9][0-9]*)\\b" - }, { - token : "constant.binary", - regex : "<[0-9A-Fa-f][0-9A-Fa-f](\\s+[0-9A-Fa-f][0-9A-Fa-f])*>" - }, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" - }, { - token : "constant.language.null", - regex : "null\\b" - }, { - token : "storage.type", - regex: "(?:Integer|Boolean|Null|String|Buffer|Tuple|List|Object|Function|Coroutine|Form)\\b" - }, { - token : "keyword", - regex : "(?:return|abort|vars|for|delete|in|is|escape|exec|split|and|if|elif|else|while)\\b" - }, { - token : "language.builtin", - 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" - }, { - token : "comment", - regex : "--.*$" - }, { - token : "paren.lparen", - regex : "[[({]" - }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "storage.form", - regex : "@[a-z]+" - }, { - token : "constant.other.symbol", - regex : ':+[a-zA-Z_]([-]?[a-zA-Z0-9_])*[?!]?' - }, { - token : "variable", - regex : '[a-zA-Z_]([-]?[a-zA-Z0-9_])*[?!]?' - }, { - token : "keyword.operator", - regex : "\\|\\||\\^\\^|&&|!=|==|<=|<|>=|>|\\+|-|\\*|\\/|\\^|\\%|\\#|\\!" - }, { - token : "text", - regex : "\\s+" - } - ], - "string1" : [ - { - token : "constant.language.escape", - regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|['"\\\/bfnrt])/ - }, { - token : "string", - regex : "[^'\\\\]+" - }, { - token : "string", - regex : "'", - next : "start" - }, { - token : "string", - regex : "", - next : "start" - } - ], - "string2" : [ - { - token : "constant.language.escape", - regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|['"\\\/bfnrt])/ - }, { - token : "string", - regex : '[^"\\\\]+' - }, { - token : "string", - regex : '"', - next : "start" - }, { - token : "string", - regex : "", - next : "start" - } - ] - }; - -}; - -oop.inherits(JackHighlightRules, TextHighlightRules); - -exports.JackHighlightRules = JackHighlightRules; -}); diff --git a/lib/ace/mode/jade.js b/lib/ace/mode/jade.js deleted file mode 100644 index fb2027665a1..00000000000 --- a/lib/ace/mode/jade.js +++ /dev/null @@ -1,57 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * Garen J. Torikian - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var JadeHighlightRules = require("./jade_highlight_rules").JadeHighlightRules; -var FoldMode = require("./folding/coffee").FoldMode; - -var Mode = function() { - this.HighlightRules = JadeHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.$id = "ace/mode/jade"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/java.js b/lib/ace/mode/java.js deleted file mode 100644 index 58df0c9687c..00000000000 --- a/lib/ace/mode/java.js +++ /dev/null @@ -1,24 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var JavaScriptMode = require("./javascript").Mode; -var JavaHighlightRules = require("./java_highlight_rules").JavaHighlightRules; - -var Mode = function() { - JavaScriptMode.call(this); - this.HighlightRules = JavaHighlightRules; -}; -oop.inherits(Mode, JavaScriptMode); - -(function() { - - this.createWorker = function(session) { - return null; - }; - - this.$id = "ace/mode/java"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/java_highlight_rules.js b/lib/ace/mode/java_highlight_rules.js deleted file mode 100644 index 0f28b7176b3..00000000000 --- a/lib/ace/mode/java_highlight_rules.js +++ /dev/null @@ -1,161 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var JavaHighlightRules = function() { - - // taken from http://download.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html - var keywords = ( - "abstract|continue|for|new|switch|" + - "assert|default|goto|package|synchronized|" + - "boolean|do|if|private|this|" + - "break|double|implements|protected|throw|" + - "byte|else|import|public|throws|" + - "case|enum|instanceof|return|transient|" + - "catch|extends|int|short|try|" + - "char|final|interface|static|void|" + - "class|finally|long|strictfp|volatile|" + - "const|float|native|super|while|" + - "var" - ); - - var buildinConstants = ("null|Infinity|NaN|undefined"); - - - var langClasses = ( - "AbstractMethodError|AssertionError|ClassCircularityError|"+ - "ClassFormatError|Deprecated|EnumConstantNotPresentException|"+ - "ExceptionInInitializerError|IllegalAccessError|"+ - "IllegalThreadStateException|InstantiationError|InternalError|"+ - "NegativeArraySizeException|NoSuchFieldError|Override|Process|"+ - "ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|"+ - "SuppressWarnings|TypeNotPresentException|UnknownError|"+ - "UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|"+ - "InstantiationException|IndexOutOfBoundsException|"+ - "ArrayIndexOutOfBoundsException|CloneNotSupportedException|"+ - "NoSuchFieldException|IllegalArgumentException|NumberFormatException|"+ - "SecurityException|Void|InheritableThreadLocal|IllegalStateException|"+ - "InterruptedException|NoSuchMethodException|IllegalAccessException|"+ - "UnsupportedOperationException|Enum|StrictMath|Package|Compiler|"+ - "Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|"+ - "NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|"+ - "NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|"+ - "Character|Boolean|StackTraceElement|Appendable|StringBuffer|"+ - "Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|"+ - "StackOverflowError|OutOfMemoryError|VirtualMachineError|"+ - "ArrayStoreException|ClassCastException|LinkageError|"+ - "NoClassDefFoundError|ClassNotFoundException|RuntimeException|"+ - "Exception|ThreadDeath|Error|Throwable|System|ClassLoader|"+ - "Cloneable|Class|CharSequence|Comparable|String|Object" - ); - - var keywordMapper = this.createKeywordMapper({ - "variable.language": "this", - "keyword": keywords, - "constant.language": buildinConstants, - "support.function": langClasses - }, "identifier"); - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { - "start" : [ - { - token : "comment", - regex : "\\/\\/.*$" - }, - DocCommentHighlightRules.getStartRule("doc-start"), - { - token : "comment", // multi line comment - regex : "\\/\\*", - next : "comment" - }, { - token : "string", // single line - regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - }, { - token : "string", // single line - regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, { - token : "constant.numeric", // hex - regex : /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\b/ - }, { - token : "constant.numeric", // float - regex : /[+-]?\d[\d_]*(?:(?:\.[\d_]*)?(?:[eE][+-]?[\d_]+)?)?[LlSsDdFfYy]?\b/ - }, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" - }, { - regex: "(open(?:\\s+))?module(?=\\s*\\w)", - token: "keyword", - next: [{ - regex: "{", - token: "paren.lparen", - next: [{ - regex: "}", - token: "paren.rparen", - next: "start" - }, { - // From Section 3.9 of http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jls-diffs.pdf - regex: "\\b(requires|transitive|exports|opens|to|uses|provides|with)\\b", - token: "keyword" - }] - }, { - token : "text", - regex : "\\s+" - }, { - token : "identifier", - regex : "\\w+" - }, { - token : "punctuation.operator", - regex : "." - }, { - token : "text", - regex : "\\s+" - }, { - regex: "", // exit if there is anything else - next: "start" - }] - }, { - token : keywordMapper, - // TODO: Unicode escape sequences - // TODO: Unicode identifiers - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" - }, { - token : "lparen", - regex : "[[({]" - }, { - token : "rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" - } - ], - "comment" : [ - { - token : "comment", // closing comment - regex : "\\*\\/", - next : "start" - }, { - defaultToken : "comment" - } - ] - }; - - - this.embedRules(DocCommentHighlightRules, "doc-", - [ DocCommentHighlightRules.getEndRule("start") ]); - this.normalizeRules(); -}; - -oop.inherits(JavaHighlightRules, TextHighlightRules); - -exports.JavaHighlightRules = JavaHighlightRules; -}); diff --git a/lib/ace/mode/javascript.js b/lib/ace/mode/javascript.js deleted file mode 100644 index 509c271cb32..00000000000 --- a/lib/ace/mode/javascript.js +++ /dev/null @@ -1,116 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var WorkerClient = require("../worker/worker_client").WorkerClient; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = JavaScriptHighlightRules; - - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - this.$quotes = {'"': '"', "'": "'", "`": "`"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start" || state == "no_regex") { - var match = line.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/); - if (match) { - indent += tab; - } - } else if (state == "doc-start") { - if (endState == "start" || endState == "no_regex") { - return ""; - } - var match = line.match(/^\s*(\/?)\*/); - if (match) { - if (match[1]) { - indent += " "; - } - indent += "* "; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.createWorker = function(session) { - var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker"); - worker.attachToDocument(session.getDocument()); - - worker.on("annotate", function(results) { - session.setAnnotations(results.data); - }); - - worker.on("terminate", function() { - session.clearAnnotations(); - }); - - return worker; - }; - - this.$id = "ace/mode/javascript"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/javascript/jshint.js b/lib/ace/mode/javascript/jshint.js index 4bafb996c17..adc51597e48 100644 --- a/lib/ace/mode/javascript/jshint.js +++ b/lib/ace/mode/javascript/jshint.js @@ -22,11710 +22,17079 @@ module.exports = (function outer (modules, cache, entry) { for(var i=0;i= 65 && i <= 90 || // A-Z + i === 95 || // _ + i >= 97 && i <= 122; // a-z } -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; +var identifierPartTable = []; -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; +for (var i = 0; i < 128; i++) { + identifierPartTable[i] = + identifierStartTable[i] || // $, _, A-Z, a-z + i >= 48 && i <= 57; // 0-9 +} -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; +module.exports = { + asciiIdentifierStartTable: identifierStartTable, + asciiIdentifierPartTable: identifierPartTable }; -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - - if (!this._events) - this._events = {}; +},{}],"/../../../jshint/data/es5-identifier-names.js":[function(_dereq_,module,exports){ +module.exports = /^(?:[\$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0525\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0621-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971\u0972\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D3D\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC\u0EDD\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8B\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10D0-\u10FA\u10FC\u1100-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u2094\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2D00-\u2D25\u2D30-\u2D65\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31B7\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCB\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA65F\uA662-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B\uA78C\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA2D\uFA30-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC])(?:[\$0-9A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0525\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0621-\u065E\u0660-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0900-\u0939\u093C-\u094E\u0950-\u0955\u0958-\u0963\u0966-\u096F\u0971\u0972\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC\u0EDD\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F8B\u0F90-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10D0-\u10FA\u10FC\u1100-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17B3\u17B6-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BAA\u1BAE-\u1BB9\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF2\u1D00-\u1DE6\u1DFD-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u2094\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF1\u2D00-\u2D25\u2D30-\u2D65\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31B7\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCB\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA65F\uA662-\uA66F\uA67C\uA67D\uA67F-\uA697\uA6A0-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B\uA78C\uA7FB-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA2D\uFA30-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC])*$/; +},{}],"/../../../jshint/data/non-ascii-identifier-part-only.js":[function(_dereq_,module,exports){ +var str = '183,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,903,1155,1156,1157,1158,1159,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1471,1473,1474,1476,1477,1479,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1648,1750,1751,1752,1753,1754,1755,1756,1759,1760,1761,1762,1763,1764,1767,1768,1770,1771,1772,1773,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1809,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,2027,2028,2029,2030,2031,2032,2033,2034,2035,2045,2070,2071,2072,2073,2075,2076,2077,2078,2079,2080,2081,2082,2083,2085,2086,2087,2089,2090,2091,2092,2093,2137,2138,2139,2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,2304,2305,2306,2307,2362,2363,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2385,2386,2387,2388,2389,2390,2391,2402,2403,2406,2407,2408,2409,2410,2411,2412,2413,2414,2415,2433,2434,2435,2492,2494,2495,2496,2497,2498,2499,2500,2503,2504,2507,2508,2509,2519,2530,2531,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,2558,2561,2562,2563,2620,2622,2623,2624,2625,2626,2631,2632,2635,2636,2637,2641,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2677,2689,2690,2691,2748,2750,2751,2752,2753,2754,2755,2756,2757,2759,2760,2761,2763,2764,2765,2786,2787,2790,2791,2792,2793,2794,2795,2796,2797,2798,2799,2810,2811,2812,2813,2814,2815,2817,2818,2819,2876,2878,2879,2880,2881,2882,2883,2884,2887,2888,2891,2892,2893,2902,2903,2914,2915,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2946,3006,3007,3008,3009,3010,3014,3015,3016,3018,3019,3020,3021,3031,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3072,3073,3074,3075,3076,3134,3135,3136,3137,3138,3139,3140,3142,3143,3144,3146,3147,3148,3149,3157,3158,3170,3171,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3201,3202,3203,3260,3262,3263,3264,3265,3266,3267,3268,3270,3271,3272,3274,3275,3276,3277,3285,3286,3298,3299,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,3328,3329,3330,3331,3387,3388,3390,3391,3392,3393,3394,3395,3396,3398,3399,3400,3402,3403,3404,3405,3415,3426,3427,3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3458,3459,3530,3535,3536,3537,3538,3539,3540,3542,3544,3545,3546,3547,3548,3549,3550,3551,3558,3559,3560,3561,3562,3563,3564,3565,3566,3567,3570,3571,3633,3636,3637,3638,3639,3640,3641,3642,3655,3656,3657,3658,3659,3660,3661,3662,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3761,3764,3765,3766,3767,3768,3769,3771,3772,3784,3785,3786,3787,3788,3789,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3864,3865,3872,3873,3874,3875,3876,3877,3878,3879,3880,3881,3893,3895,3897,3902,3903,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3974,3975,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4038,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4182,4183,4184,4185,4190,4191,4192,4194,4195,4196,4199,4200,4201,4202,4203,4204,4205,4209,4210,4211,4212,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4239,4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253,4957,4958,4959,4969,4970,4971,4972,4973,4974,4975,4976,4977,5906,5907,5908,5938,5939,5940,5970,5971,6002,6003,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6109,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121,6155,6156,6157,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6313,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,6470,6471,6472,6473,6474,6475,6476,6477,6478,6479,6608,6609,6610,6611,6612,6613,6614,6615,6616,6617,6618,6679,6680,6681,6682,6683,6741,6742,6743,6744,6745,6746,6747,6748,6749,6750,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779,6780,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,6832,6833,6834,6835,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6912,6913,6914,6915,6916,6964,6965,6966,6967,6968,6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6992,6993,6994,6995,6996,6997,6998,6999,7000,7001,7019,7020,7021,7022,7023,7024,7025,7026,7027,7040,7041,7042,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7088,7089,7090,7091,7092,7093,7094,7095,7096,7097,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154,7155,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7376,7377,7378,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7405,7410,7411,7412,7415,7416,7417,7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7675,7676,7677,7678,7679,8204,8205,8255,8256,8276,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8417,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,11503,11504,11505,11647,11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755,11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,12330,12331,12332,12333,12334,12335,12441,12442,42528,42529,42530,42531,42532,42533,42534,42535,42536,42537,42607,42612,42613,42614,42615,42616,42617,42618,42619,42620,42621,42654,42655,42736,42737,43010,43014,43019,43043,43044,43045,43046,43047,43136,43137,43188,43189,43190,43191,43192,43193,43194,43195,43196,43197,43198,43199,43200,43201,43202,43203,43204,43205,43216,43217,43218,43219,43220,43221,43222,43223,43224,43225,43232,43233,43234,43235,43236,43237,43238,43239,43240,43241,43242,43243,43244,43245,43246,43247,43248,43249,43263,43264,43265,43266,43267,43268,43269,43270,43271,43272,43273,43302,43303,43304,43305,43306,43307,43308,43309,43335,43336,43337,43338,43339,43340,43341,43342,43343,43344,43345,43346,43347,43392,43393,43394,43395,43443,43444,43445,43446,43447,43448,43449,43450,43451,43452,43453,43454,43455,43456,43472,43473,43474,43475,43476,43477,43478,43479,43480,43481,43493,43504,43505,43506,43507,43508,43509,43510,43511,43512,43513,43561,43562,43563,43564,43565,43566,43567,43568,43569,43570,43571,43572,43573,43574,43587,43596,43597,43600,43601,43602,43603,43604,43605,43606,43607,43608,43609,43643,43644,43645,43696,43698,43699,43700,43703,43704,43710,43711,43713,43755,43756,43757,43758,43759,43765,43766,44003,44004,44005,44006,44007,44008,44009,44010,44012,44013,44016,44017,44018,44019,44020,44021,44022,44023,44024,44025,64286,65024,65025,65026,65027,65028,65029,65030,65031,65032,65033,65034,65035,65036,65037,65038,65039,65056,65057,65058,65059,65060,65061,65062,65063,65064,65065,65066,65067,65068,65069,65070,65071,65075,65076,65101,65102,65103,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65343'; +var arr = str.split(',').map(function(code) { + return parseInt(code, 10); +}); +module.exports = arr; +},{}],"/../../../jshint/data/non-ascii-identifier-start.js":[function(_dereq_,module,exports){ +var str = '170,181,186,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,710,711,712,713,714,715,716,717,718,719,720,721,736,737,738,739,740,748,750,880,881,882,883,884,886,887,890,891,892,893,895,902,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1369,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1519,1520,1521,1522,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1646,1647,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1749,1765,1766,1774,1775,1786,1787,1788,1791,1808,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1969,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2036,2037,2042,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2074,2084,2088,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,2208,2209,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,2230,2231,2232,2233,2234,2235,2236,2237,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2365,2384,2392,2393,2394,2395,2396,2397,2398,2399,2400,2401,2417,2418,2419,2420,2421,2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2437,2438,2439,2440,2441,2442,2443,2444,2447,2448,2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,2469,2470,2471,2472,2474,2475,2476,2477,2478,2479,2480,2482,2486,2487,2488,2489,2493,2510,2524,2525,2527,2528,2529,2544,2545,2556,2565,2566,2567,2568,2569,2570,2575,2576,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2602,2603,2604,2605,2606,2607,2608,2610,2611,2613,2614,2616,2617,2649,2650,2651,2652,2654,2674,2675,2676,2693,2694,2695,2696,2697,2698,2699,2700,2701,2703,2704,2705,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,2724,2725,2726,2727,2728,2730,2731,2732,2733,2734,2735,2736,2738,2739,2741,2742,2743,2744,2745,2749,2768,2784,2785,2809,2821,2822,2823,2824,2825,2826,2827,2828,2831,2832,2835,2836,2837,2838,2839,2840,2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2858,2859,2860,2861,2862,2863,2864,2866,2867,2869,2870,2871,2872,2873,2877,2908,2909,2911,2912,2913,2929,2947,2949,2950,2951,2952,2953,2954,2958,2959,2960,2962,2963,2964,2965,2969,2970,2972,2974,2975,2979,2980,2984,2985,2986,2990,2991,2992,2993,2994,2995,2996,2997,2998,2999,3000,3001,3024,3077,3078,3079,3080,3081,3082,3083,3084,3086,3087,3088,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,3129,3133,3160,3161,3162,3168,3169,3200,3205,3206,3207,3208,3209,3210,3211,3212,3214,3215,3216,3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,3234,3235,3236,3237,3238,3239,3240,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3253,3254,3255,3256,3257,3261,3294,3296,3297,3313,3314,3333,3334,3335,3336,3337,3338,3339,3340,3342,3343,3344,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3389,3406,3412,3413,3414,3423,3424,3425,3450,3451,3452,3453,3454,3455,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478,3482,3483,3484,3485,3486,3487,3488,3489,3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503,3504,3505,3507,3508,3509,3510,3511,3512,3513,3514,3515,3517,3520,3521,3522,3523,3524,3525,3526,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3634,3635,3648,3649,3650,3651,3652,3653,3654,3713,3714,3716,3719,3720,3722,3725,3732,3733,3734,3735,3737,3738,3739,3740,3741,3742,3743,3745,3746,3747,3749,3751,3754,3755,3757,3758,3759,3760,3762,3763,3773,3776,3777,3778,3779,3780,3782,3804,3805,3806,3807,3840,3904,3905,3906,3907,3908,3909,3910,3911,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3976,3977,3978,3979,3980,4096,4097,4098,4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,4138,4159,4176,4177,4178,4179,4180,4181,4186,4187,4188,4189,4193,4197,4198,4206,4207,4208,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,4224,4225,4238,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,4290,4291,4292,4293,4295,4301,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327,4328,4329,4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,4345,4346,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568,4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583,4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,4614,4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658,4659,4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4682,4683,4684,4685,4688,4689,4690,4691,4692,4693,4694,4696,4698,4699,4700,4701,4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4746,4747,4748,4749,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,4779,4780,4781,4782,4783,4784,4786,4787,4788,4789,4792,4793,4794,4795,4796,4797,4798,4800,4802,4803,4804,4805,4808,4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4882,4883,4884,4885,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003,5004,5005,5006,5007,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108,5109,5112,5113,5114,5115,5116,5117,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213,5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5792,5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5870,5871,5872,5873,5874,5875,5876,5877,5878,5879,5880,5888,5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5902,5903,5904,5905,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5998,5999,6000,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6103,6108,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,6264,6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,6309,6310,6311,6312,6314,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,6429,6430,6480,6481,6482,6483,6484,6485,6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,6504,6505,6506,6507,6508,6509,6512,6513,6514,6515,6516,6528,6529,6530,6531,6532,6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565,6566,6567,6568,6569,6570,6571,6576,6577,6578,6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6823,6917,6918,6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6981,6982,6983,6984,6985,6986,6987,7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7086,7087,7098,7099,7100,7101,7102,7103,7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,7139,7140,7141,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7245,7246,7247,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7296,7297,7298,7299,7300,7301,7302,7303,7304,7312,7313,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7357,7358,7359,7401,7402,7403,7404,7406,7407,7408,7409,7413,7414,7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759,7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7960,7961,7962,7963,7964,7965,7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983,7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999,8000,8001,8002,8003,8004,8005,8008,8009,8010,8011,8012,8013,8016,8017,8018,8019,8020,8021,8022,8023,8025,8027,8029,8031,8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047,8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8118,8119,8120,8121,8122,8123,8124,8126,8130,8131,8132,8134,8135,8136,8137,8138,8139,8140,8144,8145,8146,8147,8150,8151,8152,8153,8154,8155,8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8178,8179,8180,8182,8183,8184,8185,8186,8187,8188,8305,8319,8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8450,8455,8458,8459,8460,8461,8462,8463,8464,8465,8466,8467,8469,8472,8473,8474,8475,8476,8477,8484,8486,8488,8490,8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8508,8509,8510,8511,8517,8518,8519,8520,8521,8526,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8570,8571,8572,8573,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584,11264,11265,11266,11267,11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304,11305,11306,11307,11308,11309,11310,11312,11313,11314,11315,11316,11317,11318,11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334,11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349,11350,11351,11352,11353,11354,11355,11356,11357,11358,11360,11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,11378,11379,11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395,11396,11397,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410,11411,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425,11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441,11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,11470,11471,11472,11473,11474,11475,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486,11487,11488,11489,11490,11491,11492,11499,11500,11501,11502,11506,11507,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,11530,11531,11532,11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548,11549,11550,11551,11552,11553,11554,11555,11556,11557,11559,11565,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,11605,11606,11607,11608,11609,11610,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622,11623,11631,11648,11649,11650,11651,11652,11653,11654,11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670,11680,11681,11682,11683,11684,11685,11686,11688,11689,11690,11691,11692,11693,11694,11696,11697,11698,11699,11700,11701,11702,11704,11705,11706,11707,11708,11709,11710,11712,11713,11714,11715,11716,11717,11718,11720,11721,11722,11723,11724,11725,11726,11728,11729,11730,11731,11732,11733,11734,11736,11737,11738,11739,11740,11741,11742,12293,12294,12295,12321,12322,12323,12324,12325,12326,12327,12328,12329,12337,12338,12339,12340,12341,12344,12345,12346,12347,12348,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,12436,12437,12438,12443,12444,12445,12446,12447,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,12540,12541,12542,12543,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,12584,12585,12586,12587,12588,12589,12590,12591,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682,12683,12684,12685,12686,12704,12705,12706,12707,12708,12709,12710,12711,12712,12713,12714,12715,12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726,12727,12728,12729,12730,12784,12785,12786,12787,12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321,13322,13323,13324,13325,13326,13327,13328,13329,13330,13331,13332,13333,13334,13335,13336,13337,13338,13339,13340,13341,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351,13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382,13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398,13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414,13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435,13436,13437,13438,13439,13440,13441,13442,13443,13444,13445,13446,13447,13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,13458,13459,13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,13471,13472,13473,13474,13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,13487,13488,13489,13490,13491,13492,13493,13494,13495,13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506,13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522,13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,13535,13536,13537,13538,13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554,13555,13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570,13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,13583,13584,13585,13586,13587,13588,13589,13590,13591,13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602,13603,13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618,13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,13631,13632,13633,13634,13635,13636,13637,13638,13639,13640,13641,13642,13643,13644,13645,13646,13647,13648,13649,13650,13651,13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,13664,13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,13679,13680,13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,13691,13692,13693,13694,13695,13696,13697,13698,13699,13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,13712,13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,13727,13728,13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,13739,13740,13741,13742,13743,13744,13745,13746,13747,13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,13760,13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,13775,13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,13787,13788,13789,13790,13791,13792,13793,13794,13795,13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807,13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,13823,13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,13835,13836,13837,13838,13839,13840,13841,13842,13843,13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855,13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,13871,13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,13883,13884,13885,13886,13887,13888,13889,13890,13891,13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903,13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,13919,13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,13931,13932,13933,13934,13935,13936,13937,13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951,13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,13967,13968,13969,13970,13971,13972,13973,13974,13975,13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,13988,13989,13990,13991,13992,13993,13994,13995,13996,13997,13998,13999,14000,14001,14002,14003,14004,14005,14006,14007,14008,14009,14010,14011,14012,14013,14014,14015,14016,14017,14018,14019,14020,14021,14022,14023,14024,14025,14026,14027,14028,14029,14030,14031,14032,14033,14034,14035,14036,14037,14038,14039,14040,14041,14042,14043,14044,14045,14046,14047,14048,14049,14050,14051,14052,14053,14054,14055,14056,14057,14058,14059,14060,14061,14062,14063,14064,14065,14066,14067,14068,14069,14070,14071,14072,14073,14074,14075,14076,14077,14078,14079,14080,14081,14082,14083,14084,14085,14086,14087,14088,14089,14090,14091,14092,14093,14094,14095,14096,14097,14098,14099,14100,14101,14102,14103,14104,14105,14106,14107,14108,14109,14110,14111,14112,14113,14114,14115,14116,14117,14118,14119,14120,14121,14122,14123,14124,14125,14126,14127,14128,14129,14130,14131,14132,14133,14134,14135,14136,14137,14138,14139,14140,14141,14142,14143,14144,14145,14146,14147,14148,14149,14150,14151,14152,14153,14154,14155,14156,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167,14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179,14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191,14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203,14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215,14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239,14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251,14252,14253,14254,14255,14256,14257,14258,14259,14260,14261,14262,14263,14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275,14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287,14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299,14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311,14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323,14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335,14336,14337,14338,14339,14340,14341,14342,14343,14344,14345,14346,14347,14348,14349,14350,14351,14352,14353,14354,14355,14356,14357,14358,14359,14360,14361,14362,14363,14364,14365,14366,14367,14368,14369,14370,14371,14372,14373,14374,14375,14376,14377,14378,14379,14380,14381,14382,14383,14384,14385,14386,14387,14388,14389,14390,14391,14392,14393,14394,14395,14396,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407,14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419,14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443,14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455,14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467,14468,14469,14470,14471,14472,14473,14474,14475,14476,14477,14478,14479,14480,14481,14482,14483,14484,14485,14486,14487,14488,14489,14490,14491,14492,14493,14494,14495,14496,14497,14498,14499,14500,14501,14502,14503,14504,14505,14506,14507,14508,14509,14510,14511,14512,14513,14514,14515,14516,14517,14518,14519,14520,14521,14522,14523,14524,14525,14526,14527,14528,14529,14530,14531,14532,14533,14534,14535,14536,14537,14538,14539,14540,14541,14542,14543,14544,14545,14546,14547,14548,14549,14550,14551,14552,14553,14554,14555,14556,14557,14558,14559,14560,14561,14562,14563,14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14575,14576,14577,14578,14579,14580,14581,14582,14583,14584,14585,14586,14587,14588,14589,14590,14591,14592,14593,14594,14595,14596,14597,14598,14599,14600,14601,14602,14603,14604,14605,14606,14607,14608,14609,14610,14611,14612,14613,14614,14615,14616,14617,14618,14619,14620,14621,14622,14623,14624,14625,14626,14627,14628,14629,14630,14631,14632,14633,14634,14635,14636,14637,14638,14639,14640,14641,14642,14643,14644,14645,14646,14647,14648,14649,14650,14651,14652,14653,14654,14655,14656,14657,14658,14659,14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671,14672,14673,14674,14675,14676,14677,14678,14679,14680,14681,14682,14683,14684,14685,14686,14687,14688,14689,14690,14691,14692,14693,14694,14695,14696,14697,14698,14699,14700,14701,14702,14703,14704,14705,14706,14707,14708,14709,14710,14711,14712,14713,14714,14715,14716,14717,14718,14719,14720,14721,14722,14723,14724,14725,14726,14727,14728,14729,14730,14731,14732,14733,14734,14735,14736,14737,14738,14739,14740,14741,14742,14743,14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755,14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767,14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779,14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791,14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,14816,14817,14818,14819,14820,14821,14822,14823,14824,14825,14826,14827,14828,14829,14830,14831,14832,14833,14834,14835,14836,14837,14838,14839,14840,14841,14842,14843,14844,14845,14846,14847,14848,14849,14850,14851,14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863,14864,14865,14866,14867,14868,14869,14870,14871,14872,14873,14874,14875,14876,14877,14878,14879,14880,14881,14882,14883,14884,14885,14886,14887,14888,14889,14890,14891,14892,14893,14894,14895,14896,14897,14898,14899,14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911,14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923,14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935,14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947,14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959,14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971,14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983,14984,14985,14986,14987,14988,14989,14990,14991,14992,14993,14994,14995,14996,14997,14998,14999,15000,15001,15002,15003,15004,15005,15006,15007,15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019,15020,15021,15022,15023,15024,15025,15026,15027,15028,15029,15030,15031,15032,15033,15034,15035,15036,15037,15038,15039,15040,15041,15042,15043,15044,15045,15046,15047,15048,15049,15050,15051,15052,15053,15054,15055,15056,15057,15058,15059,15060,15061,15062,15063,15064,15065,15066,15067,15068,15069,15070,15071,15072,15073,15074,15075,15076,15077,15078,15079,15080,15081,15082,15083,15084,15085,15086,15087,15088,15089,15090,15091,15092,15093,15094,15095,15096,15097,15098,15099,15100,15101,15102,15103,15104,15105,15106,15107,15108,15109,15110,15111,15112,15113,15114,15115,15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127,15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15138,15139,15140,15141,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151,15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163,15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175,15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187,15188,15189,15190,15191,15192,15193,15194,15195,15196,15197,15198,15199,15200,15201,15202,15203,15204,15205,15206,15207,15208,15209,15210,15211,15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223,15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235,15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247,15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259,15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271,15272,15273,15274,15275,15276,15277,15278,15279,15280,15281,15282,15283,15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307,15308,15309,15310,15311,15312,15313,15314,15315,15316,15317,15318,15319,15320,15321,15322,15323,15324,15325,15326,15327,15328,15329,15330,15331,15332,15333,15334,15335,15336,15337,15338,15339,15340,15341,15342,15343,15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355,15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367,15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391,15392,15393,15394,15395,15396,15397,15398,15399,15400,15401,15402,15403,15404,15405,15406,15407,15408,15409,15410,15411,15412,15413,15414,15415,15416,15417,15418,15419,15420,15421,15422,15423,15424,15425,15426,15427,15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439,15440,15441,15442,15443,15444,15445,15446,15447,15448,15449,15450,15451,15452,15453,15454,15455,15456,15457,15458,15459,15460,15461,15462,15463,15464,15465,15466,15467,15468,15469,15470,15471,15472,15473,15474,15475,15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487,15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499,15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511,15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523,15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535,15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547,15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559,15560,15561,15562,15563,15564,15565,15566,15567,15568,15569,15570,15571,15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583,15584,15585,15586,15587,15588,15589,15590,15591,15592,15593,15594,15595,15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607,15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619,15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631,15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643,15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655,15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667,15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679,15680,15681,15682,15683,15684,15685,15686,15687,15688,15689,15690,15691,15692,15693,15694,15695,15696,15697,15698,15699,15700,15701,15702,15703,15704,15705,15706,15707,15708,15709,15710,15711,15712,15713,15714,15715,15716,15717,15718,15719,15720,15721,15722,15723,15724,15725,15726,15727,15728,15729,15730,15731,15732,15733,15734,15735,15736,15737,15738,15739,15740,15741,15742,15743,15744,15745,15746,15747,15748,15749,15750,15751,15752,15753,15754,15755,15756,15757,15758,15759,15760,15761,15762,15763,15764,15765,15766,15767,15768,15769,15770,15771,15772,15773,15774,15775,15776,15777,15778,15779,15780,15781,15782,15783,15784,15785,15786,15787,15788,15789,15790,15791,15792,15793,15794,15795,15796,15797,15798,15799,15800,15801,15802,15803,15804,15805,15806,15807,15808,15809,15810,15811,15812,15813,15814,15815,15816,15817,15818,15819,15820,15821,15822,15823,15824,15825,15826,15827,15828,15829,15830,15831,15832,15833,15834,15835,15836,15837,15838,15839,15840,15841,15842,15843,15844,15845,15846,15847,15848,15849,15850,15851,15852,15853,15854,15855,15856,15857,15858,15859,15860,15861,15862,15863,15864,15865,15866,15867,15868,15869,15870,15871,15872,15873,15874,15875,15876,15877,15878,15879,15880,15881,15882,15883,15884,15885,15886,15887,15888,15889,15890,15891,15892,15893,15894,15895,15896,15897,15898,15899,15900,15901,15902,15903,15904,15905,15906,15907,15908,15909,15910,15911,15912,15913,15914,15915,15916,15917,15918,15919,15920,15921,15922,15923,15924,15925,15926,15927,15928,15929,15930,15931,15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943,15944,15945,15946,15947,15948,15949,15950,15951,15952,15953,15954,15955,15956,15957,15958,15959,15960,15961,15962,15963,15964,15965,15966,15967,15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979,15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991,15992,15993,15994,15995,15996,15997,15998,15999,16000,16001,16002,16003,16004,16005,16006,16007,16008,16009,16010,16011,16012,16013,16014,16015,16016,16017,16018,16019,16020,16021,16022,16023,16024,16025,16026,16027,16028,16029,16030,16031,16032,16033,16034,16035,16036,16037,16038,16039,16040,16041,16042,16043,16044,16045,16046,16047,16048,16049,16050,16051,16052,16053,16054,16055,16056,16057,16058,16059,16060,16061,16062,16063,16064,16065,16066,16067,16068,16069,16070,16071,16072,16073,16074,16075,16076,16077,16078,16079,16080,16081,16082,16083,16084,16085,16086,16087,16088,16089,16090,16091,16092,16093,16094,16095,16096,16097,16098,16099,16100,16101,16102,16103,16104,16105,16106,16107,16108,16109,16110,16111,16112,16113,16114,16115,16116,16117,16118,16119,16120,16121,16122,16123,16124,16125,16126,16127,16128,16129,16130,16131,16132,16133,16134,16135,16136,16137,16138,16139,16140,16141,16142,16143,16144,16145,16146,16147,16148,16149,16150,16151,16152,16153,16154,16155,16156,16157,16158,16159,16160,16161,16162,16163,16164,16165,16166,16167,16168,16169,16170,16171,16172,16173,16174,16175,16176,16177,16178,16179,16180,16181,16182,16183,16184,16185,16186,16187,16188,16189,16190,16191,16192,16193,16194,16195,16196,16197,16198,16199,16200,16201,16202,16203,16204,16205,16206,16207,16208,16209,16210,16211,16212,16213,16214,16215,16216,16217,16218,16219,16220,16221,16222,16223,16224,16225,16226,16227,16228,16229,16230,16231,16232,16233,16234,16235,16236,16237,16238,16239,16240,16241,16242,16243,16244,16245,16246,16247,16248,16249,16250,16251,16252,16253,16254,16255,16256,16257,16258,16259,16260,16261,16262,16263,16264,16265,16266,16267,16268,16269,16270,16271,16272,16273,16274,16275,16276,16277,16278,16279,16280,16281,16282,16283,16284,16285,16286,16287,16288,16289,16290,16291,16292,16293,16294,16295,16296,16297,16298,16299,16300,16301,16302,16303,16304,16305,16306,16307,16308,16309,16310,16311,16312,16313,16314,16315,16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16329,16330,16331,16332,16333,16334,16335,16336,16337,16338,16339,16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,16355,16356,16357,16358,16359,16360,16361,16362,16363,16364,16365,16366,16367,16368,16369,16370,16371,16372,16373,16374,16375,16376,16377,16378,16379,16380,16381,16382,16383,16384,16385,16386,16387,16388,16389,16390,16391,16392,16393,16394,16395,16396,16397,16398,16399,16400,16401,16402,16403,16404,16405,16406,16407,16408,16409,16410,16411,16412,16413,16414,16415,16416,16417,16418,16419,16420,16421,16422,16423,16424,16425,16426,16427,16428,16429,16430,16431,16432,16433,16434,16435,16436,16437,16438,16439,16440,16441,16442,16443,16444,16445,16446,16447,16448,16449,16450,16451,16452,16453,16454,16455,16456,16457,16458,16459,16460,16461,16462,16463,16464,16465,16466,16467,16468,16469,16470,16471,16472,16473,16474,16475,16476,16477,16478,16479,16480,16481,16482,16483,16484,16485,16486,16487,16488,16489,16490,16491,16492,16493,16494,16495,16496,16497,16498,16499,16500,16501,16502,16503,16504,16505,16506,16507,16508,16509,16510,16511,16512,16513,16514,16515,16516,16517,16518,16519,16520,16521,16522,16523,16524,16525,16526,16527,16528,16529,16530,16531,16532,16533,16534,16535,16536,16537,16538,16539,16540,16541,16542,16543,16544,16545,16546,16547,16548,16549,16550,16551,16552,16553,16554,16555,16556,16557,16558,16559,16560,16561,16562,16563,16564,16565,16566,16567,16568,16569,16570,16571,16572,16573,16574,16575,16576,16577,16578,16579,16580,16581,16582,16583,16584,16585,16586,16587,16588,16589,16590,16591,16592,16593,16594,16595,16596,16597,16598,16599,16600,16601,16602,16603,16604,16605,16606,16607,16608,16609,16610,16611,16612,16613,16614,16615,16616,16617,16618,16619,16620,16621,16622,16623,16624,16625,16626,16627,16628,16629,16630,16631,16632,16633,16634,16635,16636,16637,16638,16639,16640,16641,16642,16643,16644,16645,16646,16647,16648,16649,16650,16651,16652,16653,16654,16655,16656,16657,16658,16659,16660,16661,16662,16663,16664,16665,16666,16667,16668,16669,16670,16671,16672,16673,16674,16675,16676,16677,16678,16679,16680,16681,16682,16683,16684,16685,16686,16687,16688,16689,16690,16691,16692,16693,16694,16695,16696,16697,16698,16699,16700,16701,16702,16703,16704,16705,16706,16707,16708,16709,16710,16711,16712,16713,16714,16715,16716,16717,16718,16719,16720,16721,16722,16723,16724,16725,16726,16727,16728,16729,16730,16731,16732,16733,16734,16735,16736,16737,16738,16739,16740,16741,16742,16743,16744,16745,16746,16747,16748,16749,16750,16751,16752,16753,16754,16755,16756,16757,16758,16759,16760,16761,16762,16763,16764,16765,16766,16767,16768,16769,16770,16771,16772,16773,16774,16775,16776,16777,16778,16779,16780,16781,16782,16783,16784,16785,16786,16787,16788,16789,16790,16791,16792,16793,16794,16795,16796,16797,16798,16799,16800,16801,16802,16803,16804,16805,16806,16807,16808,16809,16810,16811,16812,16813,16814,16815,16816,16817,16818,16819,16820,16821,16822,16823,16824,16825,16826,16827,16828,16829,16830,16831,16832,16833,16834,16835,16836,16837,16838,16839,16840,16841,16842,16843,16844,16845,16846,16847,16848,16849,16850,16851,16852,16853,16854,16855,16856,16857,16858,16859,16860,16861,16862,16863,16864,16865,16866,16867,16868,16869,16870,16871,16872,16873,16874,16875,16876,16877,16878,16879,16880,16881,16882,16883,16884,16885,16886,16887,16888,16889,16890,16891,16892,16893,16894,16895,16896,16897,16898,16899,16900,16901,16902,16903,16904,16905,16906,16907,16908,16909,16910,16911,16912,16913,16914,16915,16916,16917,16918,16919,16920,16921,16922,16923,16924,16925,16926,16927,16928,16929,16930,16931,16932,16933,16934,16935,16936,16937,16938,16939,16940,16941,16942,16943,16944,16945,16946,16947,16948,16949,16950,16951,16952,16953,16954,16955,16956,16957,16958,16959,16960,16961,16962,16963,16964,16965,16966,16967,16968,16969,16970,16971,16972,16973,16974,16975,16976,16977,16978,16979,16980,16981,16982,16983,16984,16985,16986,16987,16988,16989,16990,16991,16992,16993,16994,16995,16996,16997,16998,16999,17000,17001,17002,17003,17004,17005,17006,17007,17008,17009,17010,17011,17012,17013,17014,17015,17016,17017,17018,17019,17020,17021,17022,17023,17024,17025,17026,17027,17028,17029,17030,17031,17032,17033,17034,17035,17036,17037,17038,17039,17040,17041,17042,17043,17044,17045,17046,17047,17048,17049,17050,17051,17052,17053,17054,17055,17056,17057,17058,17059,17060,17061,17062,17063,17064,17065,17066,17067,17068,17069,17070,17071,17072,17073,17074,17075,17076,17077,17078,17079,17080,17081,17082,17083,17084,17085,17086,17087,17088,17089,17090,17091,17092,17093,17094,17095,17096,17097,17098,17099,17100,17101,17102,17103,17104,17105,17106,17107,17108,17109,17110,17111,17112,17113,17114,17115,17116,17117,17118,17119,17120,17121,17122,17123,17124,17125,17126,17127,17128,17129,17130,17131,17132,17133,17134,17135,17136,17137,17138,17139,17140,17141,17142,17143,17144,17145,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,17156,17157,17158,17159,17160,17161,17162,17163,17164,17165,17166,17167,17168,17169,17170,17171,17172,17173,17174,17175,17176,17177,17178,17179,17180,17181,17182,17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,17195,17196,17197,17198,17199,17200,17201,17202,17203,17204,17205,17206,17207,17208,17209,17210,17211,17212,17213,17214,17215,17216,17217,17218,17219,17220,17221,17222,17223,17224,17225,17226,17227,17228,17229,17230,17231,17232,17233,17234,17235,17236,17237,17238,17239,17240,17241,17242,17243,17244,17245,17246,17247,17248,17249,17250,17251,17252,17253,17254,17255,17256,17257,17258,17259,17260,17261,17262,17263,17264,17265,17266,17267,17268,17269,17270,17271,17272,17273,17274,17275,17276,17277,17278,17279,17280,17281,17282,17283,17284,17285,17286,17287,17288,17289,17290,17291,17292,17293,17294,17295,17296,17297,17298,17299,17300,17301,17302,17303,17304,17305,17306,17307,17308,17309,17310,17311,17312,17313,17314,17315,17316,17317,17318,17319,17320,17321,17322,17323,17324,17325,17326,17327,17328,17329,17330,17331,17332,17333,17334,17335,17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,17351,17352,17353,17354,17355,17356,17357,17358,17359,17360,17361,17362,17363,17364,17365,17366,17367,17368,17369,17370,17371,17372,17373,17374,17375,17376,17377,17378,17379,17380,17381,17382,17383,17384,17385,17386,17387,17388,17389,17390,17391,17392,17393,17394,17395,17396,17397,17398,17399,17400,17401,17402,17403,17404,17405,17406,17407,17408,17409,17410,17411,17412,17413,17414,17415,17416,17417,17418,17419,17420,17421,17422,17423,17424,17425,17426,17427,17428,17429,17430,17431,17432,17433,17434,17435,17436,17437,17438,17439,17440,17441,17442,17443,17444,17445,17446,17447,17448,17449,17450,17451,17452,17453,17454,17455,17456,17457,17458,17459,17460,17461,17462,17463,17464,17465,17466,17467,17468,17469,17470,17471,17472,17473,17474,17475,17476,17477,17478,17479,17480,17481,17482,17483,17484,17485,17486,17487,17488,17489,17490,17491,17492,17493,17494,17495,17496,17497,17498,17499,17500,17501,17502,17503,17504,17505,17506,17507,17508,17509,17510,17511,17512,17513,17514,17515,17516,17517,17518,17519,17520,17521,17522,17523,17524,17525,17526,17527,17528,17529,17530,17531,17532,17533,17534,17535,17536,17537,17538,17539,17540,17541,17542,17543,17544,17545,17546,17547,17548,17549,17550,17551,17552,17553,17554,17555,17556,17557,17558,17559,17560,17561,17562,17563,17564,17565,17566,17567,17568,17569,17570,17571,17572,17573,17574,17575,17576,17577,17578,17579,17580,17581,17582,17583,17584,17585,17586,17587,17588,17589,17590,17591,17592,17593,17594,17595,17596,17597,17598,17599,17600,17601,17602,17603,17604,17605,17606,17607,17608,17609,17610,17611,17612,17613,17614,17615,17616,17617,17618,17619,17620,17621,17622,17623,17624,17625,17626,17627,17628,17629,17630,17631,17632,17633,17634,17635,17636,17637,17638,17639,17640,17641,17642,17643,17644,17645,17646,17647,17648,17649,17650,17651,17652,17653,17654,17655,17656,17657,17658,17659,17660,17661,17662,17663,17664,17665,17666,17667,17668,17669,17670,17671,17672,17673,17674,17675,17676,17677,17678,17679,17680,17681,17682,17683,17684,17685,17686,17687,17688,17689,17690,17691,17692,17693,17694,17695,17696,17697,17698,17699,17700,17701,17702,17703,17704,17705,17706,17707,17708,17709,17710,17711,17712,17713,17714,17715,17716,17717,17718,17719,17720,17721,17722,17723,17724,17725,17726,17727,17728,17729,17730,17731,17732,17733,17734,17735,17736,17737,17738,17739,17740,17741,17742,17743,17744,17745,17746,17747,17748,17749,17750,17751,17752,17753,17754,17755,17756,17757,17758,17759,17760,17761,17762,17763,17764,17765,17766,17767,17768,17769,17770,17771,17772,17773,17774,17775,17776,17777,17778,17779,17780,17781,17782,17783,17784,17785,17786,17787,17788,17789,17790,17791,17792,17793,17794,17795,17796,17797,17798,17799,17800,17801,17802,17803,17804,17805,17806,17807,17808,17809,17810,17811,17812,17813,17814,17815,17816,17817,17818,17819,17820,17821,17822,17823,17824,17825,17826,17827,17828,17829,17830,17831,17832,17833,17834,17835,17836,17837,17838,17839,17840,17841,17842,17843,17844,17845,17846,17847,17848,17849,17850,17851,17852,17853,17854,17855,17856,17857,17858,17859,17860,17861,17862,17863,17864,17865,17866,17867,17868,17869,17870,17871,17872,17873,17874,17875,17876,17877,17878,17879,17880,17881,17882,17883,17884,17885,17886,17887,17888,17889,17890,17891,17892,17893,17894,17895,17896,17897,17898,17899,17900,17901,17902,17903,17904,17905,17906,17907,17908,17909,17910,17911,17912,17913,17914,17915,17916,17917,17918,17919,17920,17921,17922,17923,17924,17925,17926,17927,17928,17929,17930,17931,17932,17933,17934,17935,17936,17937,17938,17939,17940,17941,17942,17943,17944,17945,17946,17947,17948,17949,17950,17951,17952,17953,17954,17955,17956,17957,17958,17959,17960,17961,17962,17963,17964,17965,17966,17967,17968,17969,17970,17971,17972,17973,17974,17975,17976,17977,17978,17979,17980,17981,17982,17983,17984,17985,17986,17987,17988,17989,17990,17991,17992,17993,17994,17995,17996,17997,17998,17999,18000,18001,18002,18003,18004,18005,18006,18007,18008,18009,18010,18011,18012,18013,18014,18015,18016,18017,18018,18019,18020,18021,18022,18023,18024,18025,18026,18027,18028,18029,18030,18031,18032,18033,18034,18035,18036,18037,18038,18039,18040,18041,18042,18043,18044,18045,18046,18047,18048,18049,18050,18051,18052,18053,18054,18055,18056,18057,18058,18059,18060,18061,18062,18063,18064,18065,18066,18067,18068,18069,18070,18071,18072,18073,18074,18075,18076,18077,18078,18079,18080,18081,18082,18083,18084,18085,18086,18087,18088,18089,18090,18091,18092,18093,18094,18095,18096,18097,18098,18099,18100,18101,18102,18103,18104,18105,18106,18107,18108,18109,18110,18111,18112,18113,18114,18115,18116,18117,18118,18119,18120,18121,18122,18123,18124,18125,18126,18127,18128,18129,18130,18131,18132,18133,18134,18135,18136,18137,18138,18139,18140,18141,18142,18143,18144,18145,18146,18147,18148,18149,18150,18151,18152,18153,18154,18155,18156,18157,18158,18159,18160,18161,18162,18163,18164,18165,18166,18167,18168,18169,18170,18171,18172,18173,18174,18175,18176,18177,18178,18179,18180,18181,18182,18183,18184,18185,18186,18187,18188,18189,18190,18191,18192,18193,18194,18195,18196,18197,18198,18199,18200,18201,18202,18203,18204,18205,18206,18207,18208,18209,18210,18211,18212,18213,18214,18215,18216,18217,18218,18219,18220,18221,18222,18223,18224,18225,18226,18227,18228,18229,18230,18231,18232,18233,18234,18235,18236,18237,18238,18239,18240,18241,18242,18243,18244,18245,18246,18247,18248,18249,18250,18251,18252,18253,18254,18255,18256,18257,18258,18259,18260,18261,18262,18263,18264,18265,18266,18267,18268,18269,18270,18271,18272,18273,18274,18275,18276,18277,18278,18279,18280,18281,18282,18283,18284,18285,18286,18287,18288,18289,18290,18291,18292,18293,18294,18295,18296,18297,18298,18299,18300,18301,18302,18303,18304,18305,18306,18307,18308,18309,18310,18311,18312,18313,18314,18315,18316,18317,18318,18319,18320,18321,18322,18323,18324,18325,18326,18327,18328,18329,18330,18331,18332,18333,18334,18335,18336,18337,18338,18339,18340,18341,18342,18343,18344,18345,18346,18347,18348,18349,18350,18351,18352,18353,18354,18355,18356,18357,18358,18359,18360,18361,18362,18363,18364,18365,18366,18367,18368,18369,18370,18371,18372,18373,18374,18375,18376,18377,18378,18379,18380,18381,18382,18383,18384,18385,18386,18387,18388,18389,18390,18391,18392,18393,18394,18395,18396,18397,18398,18399,18400,18401,18402,18403,18404,18405,18406,18407,18408,18409,18410,18411,18412,18413,18414,18415,18416,18417,18418,18419,18420,18421,18422,18423,18424,18425,18426,18427,18428,18429,18430,18431,18432,18433,18434,18435,18436,18437,18438,18439,18440,18441,18442,18443,18444,18445,18446,18447,18448,18449,18450,18451,18452,18453,18454,18455,18456,18457,18458,18459,18460,18461,18462,18463,18464,18465,18466,18467,18468,18469,18470,18471,18472,18473,18474,18475,18476,18477,18478,18479,18480,18481,18482,18483,18484,18485,18486,18487,18488,18489,18490,18491,18492,18493,18494,18495,18496,18497,18498,18499,18500,18501,18502,18503,18504,18505,18506,18507,18508,18509,18510,18511,18512,18513,18514,18515,18516,18517,18518,18519,18520,18521,18522,18523,18524,18525,18526,18527,18528,18529,18530,18531,18532,18533,18534,18535,18536,18537,18538,18539,18540,18541,18542,18543,18544,18545,18546,18547,18548,18549,18550,18551,18552,18553,18554,18555,18556,18557,18558,18559,18560,18561,18562,18563,18564,18565,18566,18567,18568,18569,18570,18571,18572,18573,18574,18575,18576,18577,18578,18579,18580,18581,18582,18583,18584,18585,18586,18587,18588,18589,18590,18591,18592,18593,18594,18595,18596,18597,18598,18599,18600,18601,18602,18603,18604,18605,18606,18607,18608,18609,18610,18611,18612,18613,18614,18615,18616,18617,18618,18619,18620,18621,18622,18623,18624,18625,18626,18627,18628,18629,18630,18631,18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18643,18644,18645,18646,18647,18648,18649,18650,18651,18652,18653,18654,18655,18656,18657,18658,18659,18660,18661,18662,18663,18664,18665,18666,18667,18668,18669,18670,18671,18672,18673,18674,18675,18676,18677,18678,18679,18680,18681,18682,18683,18684,18685,18686,18687,18688,18689,18690,18691,18692,18693,18694,18695,18696,18697,18698,18699,18700,18701,18702,18703,18704,18705,18706,18707,18708,18709,18710,18711,18712,18713,18714,18715,18716,18717,18718,18719,18720,18721,18722,18723,18724,18725,18726,18727,18728,18729,18730,18731,18732,18733,18734,18735,18736,18737,18738,18739,18740,18741,18742,18743,18744,18745,18746,18747,18748,18749,18750,18751,18752,18753,18754,18755,18756,18757,18758,18759,18760,18761,18762,18763,18764,18765,18766,18767,18768,18769,18770,18771,18772,18773,18774,18775,18776,18777,18778,18779,18780,18781,18782,18783,18784,18785,18786,18787,18788,18789,18790,18791,18792,18793,18794,18795,18796,18797,18798,18799,18800,18801,18802,18803,18804,18805,18806,18807,18808,18809,18810,18811,18812,18813,18814,18815,18816,18817,18818,18819,18820,18821,18822,18823,18824,18825,18826,18827,18828,18829,18830,18831,18832,18833,18834,18835,18836,18837,18838,18839,18840,18841,18842,18843,18844,18845,18846,18847,18848,18849,18850,18851,18852,18853,18854,18855,18856,18857,18858,18859,18860,18861,18862,18863,18864,18865,18866,18867,18868,18869,18870,18871,18872,18873,18874,18875,18876,18877,18878,18879,18880,18881,18882,18883,18884,18885,18886,18887,18888,18889,18890,18891,18892,18893,18894,18895,18896,18897,18898,18899,18900,18901,18902,18903,18904,18905,18906,18907,18908,18909,18910,18911,18912,18913,18914,18915,18916,18917,18918,18919,18920,18921,18922,18923,18924,18925,18926,18927,18928,18929,18930,18931,18932,18933,18934,18935,18936,18937,18938,18939,18940,18941,18942,18943,18944,18945,18946,18947,18948,18949,18950,18951,18952,18953,18954,18955,18956,18957,18958,18959,18960,18961,18962,18963,18964,18965,18966,18967,18968,18969,18970,18971,18972,18973,18974,18975,18976,18977,18978,18979,18980,18981,18982,18983,18984,18985,18986,18987,18988,18989,18990,18991,18992,18993,18994,18995,18996,18997,18998,18999,19000,19001,19002,19003,19004,19005,19006,19007,19008,19009,19010,19011,19012,19013,19014,19015,19016,19017,19018,19019,19020,19021,19022,19023,19024,19025,19026,19027,19028,19029,19030,19031,19032,19033,19034,19035,19036,19037,19038,19039,19040,19041,19042,19043,19044,19045,19046,19047,19048,19049,19050,19051,19052,19053,19054,19055,19056,19057,19058,19059,19060,19061,19062,19063,19064,19065,19066,19067,19068,19069,19070,19071,19072,19073,19074,19075,19076,19077,19078,19079,19080,19081,19082,19083,19084,19085,19086,19087,19088,19089,19090,19091,19092,19093,19094,19095,19096,19097,19098,19099,19100,19101,19102,19103,19104,19105,19106,19107,19108,19109,19110,19111,19112,19113,19114,19115,19116,19117,19118,19119,19120,19121,19122,19123,19124,19125,19126,19127,19128,19129,19130,19131,19132,19133,19134,19135,19136,19137,19138,19139,19140,19141,19142,19143,19144,19145,19146,19147,19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159,19160,19161,19162,19163,19164,19165,19166,19167,19168,19169,19170,19171,19172,19173,19174,19175,19176,19177,19178,19179,19180,19181,19182,19183,19184,19185,19186,19187,19188,19189,19190,19191,19192,19193,19194,19195,19196,19197,19198,19199,19200,19201,19202,19203,19204,19205,19206,19207,19208,19209,19210,19211,19212,19213,19214,19215,19216,19217,19218,19219,19220,19221,19222,19223,19224,19225,19226,19227,19228,19229,19230,19231,19232,19233,19234,19235,19236,19237,19238,19239,19240,19241,19242,19243,19244,19245,19246,19247,19248,19249,19250,19251,19252,19253,19254,19255,19256,19257,19258,19259,19260,19261,19262,19263,19264,19265,19266,19267,19268,19269,19270,19271,19272,19273,19274,19275,19276,19277,19278,19279,19280,19281,19282,19283,19284,19285,19286,19287,19288,19289,19290,19291,19292,19293,19294,19295,19296,19297,19298,19299,19300,19301,19302,19303,19304,19305,19306,19307,19308,19309,19310,19311,19312,19313,19314,19315,19316,19317,19318,19319,19320,19321,19322,19323,19324,19325,19326,19327,19328,19329,19330,19331,19332,19333,19334,19335,19336,19337,19338,19339,19340,19341,19342,19343,19344,19345,19346,19347,19348,19349,19350,19351,19352,19353,19354,19355,19356,19357,19358,19359,19360,19361,19362,19363,19364,19365,19366,19367,19368,19369,19370,19371,19372,19373,19374,19375,19376,19377,19378,19379,19380,19381,19382,19383,19384,19385,19386,19387,19388,19389,19390,19391,19392,19393,19394,19395,19396,19397,19398,19399,19400,19401,19402,19403,19404,19405,19406,19407,19408,19409,19410,19411,19412,19413,19414,19415,19416,19417,19418,19419,19420,19421,19422,19423,19424,19425,19426,19427,19428,19429,19430,19431,19432,19433,19434,19435,19436,19437,19438,19439,19440,19441,19442,19443,19444,19445,19446,19447,19448,19449,19450,19451,19452,19453,19454,19455,19456,19457,19458,19459,19460,19461,19462,19463,19464,19465,19466,19467,19468,19469,19470,19471,19472,19473,19474,19475,19476,19477,19478,19479,19480,19481,19482,19483,19484,19485,19486,19487,19488,19489,19490,19491,19492,19493,19494,19495,19496,19497,19498,19499,19500,19501,19502,19503,19504,19505,19506,19507,19508,19509,19510,19511,19512,19513,19514,19515,19516,19517,19518,19519,19520,19521,19522,19523,19524,19525,19526,19527,19528,19529,19530,19531,19532,19533,19534,19535,19536,19537,19538,19539,19540,19541,19542,19543,19544,19545,19546,19547,19548,19549,19550,19551,19552,19553,19554,19555,19556,19557,19558,19559,19560,19561,19562,19563,19564,19565,19566,19567,19568,19569,19570,19571,19572,19573,19574,19575,19576,19577,19578,19579,19580,19581,19582,19583,19584,19585,19586,19587,19588,19589,19590,19591,19592,19593,19594,19595,19596,19597,19598,19599,19600,19601,19602,19603,19604,19605,19606,19607,19608,19609,19610,19611,19612,19613,19614,19615,19616,19617,19618,19619,19620,19621,19622,19623,19624,19625,19626,19627,19628,19629,19630,19631,19632,19633,19634,19635,19636,19637,19638,19639,19640,19641,19642,19643,19644,19645,19646,19647,19648,19649,19650,19651,19652,19653,19654,19655,19656,19657,19658,19659,19660,19661,19662,19663,19664,19665,19666,19667,19668,19669,19670,19671,19672,19673,19674,19675,19676,19677,19678,19679,19680,19681,19682,19683,19684,19685,19686,19687,19688,19689,19690,19691,19692,19693,19694,19695,19696,19697,19698,19699,19700,19701,19702,19703,19704,19705,19706,19707,19708,19709,19710,19711,19712,19713,19714,19715,19716,19717,19718,19719,19720,19721,19722,19723,19724,19725,19726,19727,19728,19729,19730,19731,19732,19733,19734,19735,19736,19737,19738,19739,19740,19741,19742,19743,19744,19745,19746,19747,19748,19749,19750,19751,19752,19753,19754,19755,19756,19757,19758,19759,19760,19761,19762,19763,19764,19765,19766,19767,19768,19769,19770,19771,19772,19773,19774,19775,19776,19777,19778,19779,19780,19781,19782,19783,19784,19785,19786,19787,19788,19789,19790,19791,19792,19793,19794,19795,19796,19797,19798,19799,19800,19801,19802,19803,19804,19805,19806,19807,19808,19809,19810,19811,19812,19813,19814,19815,19816,19817,19818,19819,19820,19821,19822,19823,19824,19825,19826,19827,19828,19829,19830,19831,19832,19833,19834,19835,19836,19837,19838,19839,19840,19841,19842,19843,19844,19845,19846,19847,19848,19849,19850,19851,19852,19853,19854,19855,19856,19857,19858,19859,19860,19861,19862,19863,19864,19865,19866,19867,19868,19869,19870,19871,19872,19873,19874,19875,19876,19877,19878,19879,19880,19881,19882,19883,19884,19885,19886,19887,19888,19889,19890,19891,19892,19893,19968,19969,19970,19971,19972,19973,19974,19975,19976,19977,19978,19979,19980,19981,19982,19983,19984,19985,19986,19987,19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,19999,20000,20001,20002,20003,20004,20005,20006,20007,20008,20009,20010,20011,20012,20013,20014,20015,20016,20017,20018,20019,20020,20021,20022,20023,20024,20025,20026,20027,20028,20029,20030,20031,20032,20033,20034,20035,20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20047,20048,20049,20050,20051,20052,20053,20054,20055,20056,20057,20058,20059,20060,20061,20062,20063,20064,20065,20066,20067,20068,20069,20070,20071,20072,20073,20074,20075,20076,20077,20078,20079,20080,20081,20082,20083,20084,20085,20086,20087,20088,20089,20090,20091,20092,20093,20094,20095,20096,20097,20098,20099,20100,20101,20102,20103,20104,20105,20106,20107,20108,20109,20110,20111,20112,20113,20114,20115,20116,20117,20118,20119,20120,20121,20122,20123,20124,20125,20126,20127,20128,20129,20130,20131,20132,20133,20134,20135,20136,20137,20138,20139,20140,20141,20142,20143,20144,20145,20146,20147,20148,20149,20150,20151,20152,20153,20154,20155,20156,20157,20158,20159,20160,20161,20162,20163,20164,20165,20166,20167,20168,20169,20170,20171,20172,20173,20174,20175,20176,20177,20178,20179,20180,20181,20182,20183,20184,20185,20186,20187,20188,20189,20190,20191,20192,20193,20194,20195,20196,20197,20198,20199,20200,20201,20202,20203,20204,20205,20206,20207,20208,20209,20210,20211,20212,20213,20214,20215,20216,20217,20218,20219,20220,20221,20222,20223,20224,20225,20226,20227,20228,20229,20230,20231,20232,20233,20234,20235,20236,20237,20238,20239,20240,20241,20242,20243,20244,20245,20246,20247,20248,20249,20250,20251,20252,20253,20254,20255,20256,20257,20258,20259,20260,20261,20262,20263,20264,20265,20266,20267,20268,20269,20270,20271,20272,20273,20274,20275,20276,20277,20278,20279,20280,20281,20282,20283,20284,20285,20286,20287,20288,20289,20290,20291,20292,20293,20294,20295,20296,20297,20298,20299,20300,20301,20302,20303,20304,20305,20306,20307,20308,20309,20310,20311,20312,20313,20314,20315,20316,20317,20318,20319,20320,20321,20322,20323,20324,20325,20326,20327,20328,20329,20330,20331,20332,20333,20334,20335,20336,20337,20338,20339,20340,20341,20342,20343,20344,20345,20346,20347,20348,20349,20350,20351,20352,20353,20354,20355,20356,20357,20358,20359,20360,20361,20362,20363,20364,20365,20366,20367,20368,20369,20370,20371,20372,20373,20374,20375,20376,20377,20378,20379,20380,20381,20382,20383,20384,20385,20386,20387,20388,20389,20390,20391,20392,20393,20394,20395,20396,20397,20398,20399,20400,20401,20402,20403,20404,20405,20406,20407,20408,20409,20410,20411,20412,20413,20414,20415,20416,20417,20418,20419,20420,20421,20422,20423,20424,20425,20426,20427,20428,20429,20430,20431,20432,20433,20434,20435,20436,20437,20438,20439,20440,20441,20442,20443,20444,20445,20446,20447,20448,20449,20450,20451,20452,20453,20454,20455,20456,20457,20458,20459,20460,20461,20462,20463,20464,20465,20466,20467,20468,20469,20470,20471,20472,20473,20474,20475,20476,20477,20478,20479,20480,20481,20482,20483,20484,20485,20486,20487,20488,20489,20490,20491,20492,20493,20494,20495,20496,20497,20498,20499,20500,20501,20502,20503,20504,20505,20506,20507,20508,20509,20510,20511,20512,20513,20514,20515,20516,20517,20518,20519,20520,20521,20522,20523,20524,20525,20526,20527,20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20538,20539,20540,20541,20542,20543,20544,20545,20546,20547,20548,20549,20550,20551,20552,20553,20554,20555,20556,20557,20558,20559,20560,20561,20562,20563,20564,20565,20566,20567,20568,20569,20570,20571,20572,20573,20574,20575,20576,20577,20578,20579,20580,20581,20582,20583,20584,20585,20586,20587,20588,20589,20590,20591,20592,20593,20594,20595,20596,20597,20598,20599,20600,20601,20602,20603,20604,20605,20606,20607,20608,20609,20610,20611,20612,20613,20614,20615,20616,20617,20618,20619,20620,20621,20622,20623,20624,20625,20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641,20642,20643,20644,20645,20646,20647,20648,20649,20650,20651,20652,20653,20654,20655,20656,20657,20658,20659,20660,20661,20662,20663,20664,20665,20666,20667,20668,20669,20670,20671,20672,20673,20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,20687,20688,20689,20690,20691,20692,20693,20694,20695,20696,20697,20698,20699,20700,20701,20702,20703,20704,20705,20706,20707,20708,20709,20710,20711,20712,20713,20714,20715,20716,20717,20718,20719,20720,20721,20722,20723,20724,20725,20726,20727,20728,20729,20730,20731,20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,20742,20743,20744,20745,20746,20747,20748,20749,20750,20751,20752,20753,20754,20755,20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,20768,20769,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,20795,20796,20797,20798,20799,20800,20801,20802,20803,20804,20805,20806,20807,20808,20809,20810,20811,20812,20813,20814,20815,20816,20817,20818,20819,20820,20821,20822,20823,20824,20825,20826,20827,20828,20829,20830,20831,20832,20833,20834,20835,20836,20837,20838,20839,20840,20841,20842,20843,20844,20845,20846,20847,20848,20849,20850,20851,20852,20853,20854,20855,20856,20857,20858,20859,20860,20861,20862,20863,20864,20865,20866,20867,20868,20869,20870,20871,20872,20873,20874,20875,20876,20877,20878,20879,20880,20881,20882,20883,20884,20885,20886,20887,20888,20889,20890,20891,20892,20893,20894,20895,20896,20897,20898,20899,20900,20901,20902,20903,20904,20905,20906,20907,20908,20909,20910,20911,20912,20913,20914,20915,20916,20917,20918,20919,20920,20921,20922,20923,20924,20925,20926,20927,20928,20929,20930,20931,20932,20933,20934,20935,20936,20937,20938,20939,20940,20941,20942,20943,20944,20945,20946,20947,20948,20949,20950,20951,20952,20953,20954,20955,20956,20957,20958,20959,20960,20961,20962,20963,20964,20965,20966,20967,20968,20969,20970,20971,20972,20973,20974,20975,20976,20977,20978,20979,20980,20981,20982,20983,20984,20985,20986,20987,20988,20989,20990,20991,20992,20993,20994,20995,20996,20997,20998,20999,21000,21001,21002,21003,21004,21005,21006,21007,21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019,21020,21021,21022,21023,21024,21025,21026,21027,21028,21029,21030,21031,21032,21033,21034,21035,21036,21037,21038,21039,21040,21041,21042,21043,21044,21045,21046,21047,21048,21049,21050,21051,21052,21053,21054,21055,21056,21057,21058,21059,21060,21061,21062,21063,21064,21065,21066,21067,21068,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,21079,21080,21081,21082,21083,21084,21085,21086,21087,21088,21089,21090,21091,21092,21093,21094,21095,21096,21097,21098,21099,21100,21101,21102,21103,21104,21105,21106,21107,21108,21109,21110,21111,21112,21113,21114,21115,21116,21117,21118,21119,21120,21121,21122,21123,21124,21125,21126,21127,21128,21129,21130,21131,21132,21133,21134,21135,21136,21137,21138,21139,21140,21141,21142,21143,21144,21145,21146,21147,21148,21149,21150,21151,21152,21153,21154,21155,21156,21157,21158,21159,21160,21161,21162,21163,21164,21165,21166,21167,21168,21169,21170,21171,21172,21173,21174,21175,21176,21177,21178,21179,21180,21181,21182,21183,21184,21185,21186,21187,21188,21189,21190,21191,21192,21193,21194,21195,21196,21197,21198,21199,21200,21201,21202,21203,21204,21205,21206,21207,21208,21209,21210,21211,21212,21213,21214,21215,21216,21217,21218,21219,21220,21221,21222,21223,21224,21225,21226,21227,21228,21229,21230,21231,21232,21233,21234,21235,21236,21237,21238,21239,21240,21241,21242,21243,21244,21245,21246,21247,21248,21249,21250,21251,21252,21253,21254,21255,21256,21257,21258,21259,21260,21261,21262,21263,21264,21265,21266,21267,21268,21269,21270,21271,21272,21273,21274,21275,21276,21277,21278,21279,21280,21281,21282,21283,21284,21285,21286,21287,21288,21289,21290,21291,21292,21293,21294,21295,21296,21297,21298,21299,21300,21301,21302,21303,21304,21305,21306,21307,21308,21309,21310,21311,21312,21313,21314,21315,21316,21317,21318,21319,21320,21321,21322,21323,21324,21325,21326,21327,21328,21329,21330,21331,21332,21333,21334,21335,21336,21337,21338,21339,21340,21341,21342,21343,21344,21345,21346,21347,21348,21349,21350,21351,21352,21353,21354,21355,21356,21357,21358,21359,21360,21361,21362,21363,21364,21365,21366,21367,21368,21369,21370,21371,21372,21373,21374,21375,21376,21377,21378,21379,21380,21381,21382,21383,21384,21385,21386,21387,21388,21389,21390,21391,21392,21393,21394,21395,21396,21397,21398,21399,21400,21401,21402,21403,21404,21405,21406,21407,21408,21409,21410,21411,21412,21413,21414,21415,21416,21417,21418,21419,21420,21421,21422,21423,21424,21425,21426,21427,21428,21429,21430,21431,21432,21433,21434,21435,21436,21437,21438,21439,21440,21441,21442,21443,21444,21445,21446,21447,21448,21449,21450,21451,21452,21453,21454,21455,21456,21457,21458,21459,21460,21461,21462,21463,21464,21465,21466,21467,21468,21469,21470,21471,21472,21473,21474,21475,21476,21477,21478,21479,21480,21481,21482,21483,21484,21485,21486,21487,21488,21489,21490,21491,21492,21493,21494,21495,21496,21497,21498,21499,21500,21501,21502,21503,21504,21505,21506,21507,21508,21509,21510,21511,21512,21513,21514,21515,21516,21517,21518,21519,21520,21521,21522,21523,21524,21525,21526,21527,21528,21529,21530,21531,21532,21533,21534,21535,21536,21537,21538,21539,21540,21541,21542,21543,21544,21545,21546,21547,21548,21549,21550,21551,21552,21553,21554,21555,21556,21557,21558,21559,21560,21561,21562,21563,21564,21565,21566,21567,21568,21569,21570,21571,21572,21573,21574,21575,21576,21577,21578,21579,21580,21581,21582,21583,21584,21585,21586,21587,21588,21589,21590,21591,21592,21593,21594,21595,21596,21597,21598,21599,21600,21601,21602,21603,21604,21605,21606,21607,21608,21609,21610,21611,21612,21613,21614,21615,21616,21617,21618,21619,21620,21621,21622,21623,21624,21625,21626,21627,21628,21629,21630,21631,21632,21633,21634,21635,21636,21637,21638,21639,21640,21641,21642,21643,21644,21645,21646,21647,21648,21649,21650,21651,21652,21653,21654,21655,21656,21657,21658,21659,21660,21661,21662,21663,21664,21665,21666,21667,21668,21669,21670,21671,21672,21673,21674,21675,21676,21677,21678,21679,21680,21681,21682,21683,21684,21685,21686,21687,21688,21689,21690,21691,21692,21693,21694,21695,21696,21697,21698,21699,21700,21701,21702,21703,21704,21705,21706,21707,21708,21709,21710,21711,21712,21713,21714,21715,21716,21717,21718,21719,21720,21721,21722,21723,21724,21725,21726,21727,21728,21729,21730,21731,21732,21733,21734,21735,21736,21737,21738,21739,21740,21741,21742,21743,21744,21745,21746,21747,21748,21749,21750,21751,21752,21753,21754,21755,21756,21757,21758,21759,21760,21761,21762,21763,21764,21765,21766,21767,21768,21769,21770,21771,21772,21773,21774,21775,21776,21777,21778,21779,21780,21781,21782,21783,21784,21785,21786,21787,21788,21789,21790,21791,21792,21793,21794,21795,21796,21797,21798,21799,21800,21801,21802,21803,21804,21805,21806,21807,21808,21809,21810,21811,21812,21813,21814,21815,21816,21817,21818,21819,21820,21821,21822,21823,21824,21825,21826,21827,21828,21829,21830,21831,21832,21833,21834,21835,21836,21837,21838,21839,21840,21841,21842,21843,21844,21845,21846,21847,21848,21849,21850,21851,21852,21853,21854,21855,21856,21857,21858,21859,21860,21861,21862,21863,21864,21865,21866,21867,21868,21869,21870,21871,21872,21873,21874,21875,21876,21877,21878,21879,21880,21881,21882,21883,21884,21885,21886,21887,21888,21889,21890,21891,21892,21893,21894,21895,21896,21897,21898,21899,21900,21901,21902,21903,21904,21905,21906,21907,21908,21909,21910,21911,21912,21913,21914,21915,21916,21917,21918,21919,21920,21921,21922,21923,21924,21925,21926,21927,21928,21929,21930,21931,21932,21933,21934,21935,21936,21937,21938,21939,21940,21941,21942,21943,21944,21945,21946,21947,21948,21949,21950,21951,21952,21953,21954,21955,21956,21957,21958,21959,21960,21961,21962,21963,21964,21965,21966,21967,21968,21969,21970,21971,21972,21973,21974,21975,21976,21977,21978,21979,21980,21981,21982,21983,21984,21985,21986,21987,21988,21989,21990,21991,21992,21993,21994,21995,21996,21997,21998,21999,22000,22001,22002,22003,22004,22005,22006,22007,22008,22009,22010,22011,22012,22013,22014,22015,22016,22017,22018,22019,22020,22021,22022,22023,22024,22025,22026,22027,22028,22029,22030,22031,22032,22033,22034,22035,22036,22037,22038,22039,22040,22041,22042,22043,22044,22045,22046,22047,22048,22049,22050,22051,22052,22053,22054,22055,22056,22057,22058,22059,22060,22061,22062,22063,22064,22065,22066,22067,22068,22069,22070,22071,22072,22073,22074,22075,22076,22077,22078,22079,22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22092,22093,22094,22095,22096,22097,22098,22099,22100,22101,22102,22103,22104,22105,22106,22107,22108,22109,22110,22111,22112,22113,22114,22115,22116,22117,22118,22119,22120,22121,22122,22123,22124,22125,22126,22127,22128,22129,22130,22131,22132,22133,22134,22135,22136,22137,22138,22139,22140,22141,22142,22143,22144,22145,22146,22147,22148,22149,22150,22151,22152,22153,22154,22155,22156,22157,22158,22159,22160,22161,22162,22163,22164,22165,22166,22167,22168,22169,22170,22171,22172,22173,22174,22175,22176,22177,22178,22179,22180,22181,22182,22183,22184,22185,22186,22187,22188,22189,22190,22191,22192,22193,22194,22195,22196,22197,22198,22199,22200,22201,22202,22203,22204,22205,22206,22207,22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,22218,22219,22220,22221,22222,22223,22224,22225,22226,22227,22228,22229,22230,22231,22232,22233,22234,22235,22236,22237,22238,22239,22240,22241,22242,22243,22244,22245,22246,22247,22248,22249,22250,22251,22252,22253,22254,22255,22256,22257,22258,22259,22260,22261,22262,22263,22264,22265,22266,22267,22268,22269,22270,22271,22272,22273,22274,22275,22276,22277,22278,22279,22280,22281,22282,22283,22284,22285,22286,22287,22288,22289,22290,22291,22292,22293,22294,22295,22296,22297,22298,22299,22300,22301,22302,22303,22304,22305,22306,22307,22308,22309,22310,22311,22312,22313,22314,22315,22316,22317,22318,22319,22320,22321,22322,22323,22324,22325,22326,22327,22328,22329,22330,22331,22332,22333,22334,22335,22336,22337,22338,22339,22340,22341,22342,22343,22344,22345,22346,22347,22348,22349,22350,22351,22352,22353,22354,22355,22356,22357,22358,22359,22360,22361,22362,22363,22364,22365,22366,22367,22368,22369,22370,22371,22372,22373,22374,22375,22376,22377,22378,22379,22380,22381,22382,22383,22384,22385,22386,22387,22388,22389,22390,22391,22392,22393,22394,22395,22396,22397,22398,22399,22400,22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411,22412,22413,22414,22415,22416,22417,22418,22419,22420,22421,22422,22423,22424,22425,22426,22427,22428,22429,22430,22431,22432,22433,22434,22435,22436,22437,22438,22439,22440,22441,22442,22443,22444,22445,22446,22447,22448,22449,22450,22451,22452,22453,22454,22455,22456,22457,22458,22459,22460,22461,22462,22463,22464,22465,22466,22467,22468,22469,22470,22471,22472,22473,22474,22475,22476,22477,22478,22479,22480,22481,22482,22483,22484,22485,22486,22487,22488,22489,22490,22491,22492,22493,22494,22495,22496,22497,22498,22499,22500,22501,22502,22503,22504,22505,22506,22507,22508,22509,22510,22511,22512,22513,22514,22515,22516,22517,22518,22519,22520,22521,22522,22523,22524,22525,22526,22527,22528,22529,22530,22531,22532,22533,22534,22535,22536,22537,22538,22539,22540,22541,22542,22543,22544,22545,22546,22547,22548,22549,22550,22551,22552,22553,22554,22555,22556,22557,22558,22559,22560,22561,22562,22563,22564,22565,22566,22567,22568,22569,22570,22571,22572,22573,22574,22575,22576,22577,22578,22579,22580,22581,22582,22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,22596,22597,22598,22599,22600,22601,22602,22603,22604,22605,22606,22607,22608,22609,22610,22611,22612,22613,22614,22615,22616,22617,22618,22619,22620,22621,22622,22623,22624,22625,22626,22627,22628,22629,22630,22631,22632,22633,22634,22635,22636,22637,22638,22639,22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,22653,22654,22655,22656,22657,22658,22659,22660,22661,22662,22663,22664,22665,22666,22667,22668,22669,22670,22671,22672,22673,22674,22675,22676,22677,22678,22679,22680,22681,22682,22683,22684,22685,22686,22687,22688,22689,22690,22691,22692,22693,22694,22695,22696,22697,22698,22699,22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,22710,22711,22712,22713,22714,22715,22716,22717,22718,22719,22720,22721,22722,22723,22724,22725,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22737,22738,22739,22740,22741,22742,22743,22744,22745,22746,22747,22748,22749,22750,22751,22752,22753,22754,22755,22756,22757,22758,22759,22760,22761,22762,22763,22764,22765,22766,22767,22768,22769,22770,22771,22772,22773,22774,22775,22776,22777,22778,22779,22780,22781,22782,22783,22784,22785,22786,22787,22788,22789,22790,22791,22792,22793,22794,22795,22796,22797,22798,22799,22800,22801,22802,22803,22804,22805,22806,22807,22808,22809,22810,22811,22812,22813,22814,22815,22816,22817,22818,22819,22820,22821,22822,22823,22824,22825,22826,22827,22828,22829,22830,22831,22832,22833,22834,22835,22836,22837,22838,22839,22840,22841,22842,22843,22844,22845,22846,22847,22848,22849,22850,22851,22852,22853,22854,22855,22856,22857,22858,22859,22860,22861,22862,22863,22864,22865,22866,22867,22868,22869,22870,22871,22872,22873,22874,22875,22876,22877,22878,22879,22880,22881,22882,22883,22884,22885,22886,22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,22897,22898,22899,22900,22901,22902,22903,22904,22905,22906,22907,22908,22909,22910,22911,22912,22913,22914,22915,22916,22917,22918,22919,22920,22921,22922,22923,22924,22925,22926,22927,22928,22929,22930,22931,22932,22933,22934,22935,22936,22937,22938,22939,22940,22941,22942,22943,22944,22945,22946,22947,22948,22949,22950,22951,22952,22953,22954,22955,22956,22957,22958,22959,22960,22961,22962,22963,22964,22965,22966,22967,22968,22969,22970,22971,22972,22973,22974,22975,22976,22977,22978,22979,22980,22981,22982,22983,22984,22985,22986,22987,22988,22989,22990,22991,22992,22993,22994,22995,22996,22997,22998,22999,23000,23001,23002,23003,23004,23005,23006,23007,23008,23009,23010,23011,23012,23013,23014,23015,23016,23017,23018,23019,23020,23021,23022,23023,23024,23025,23026,23027,23028,23029,23030,23031,23032,23033,23034,23035,23036,23037,23038,23039,23040,23041,23042,23043,23044,23045,23046,23047,23048,23049,23050,23051,23052,23053,23054,23055,23056,23057,23058,23059,23060,23061,23062,23063,23064,23065,23066,23067,23068,23069,23070,23071,23072,23073,23074,23075,23076,23077,23078,23079,23080,23081,23082,23083,23084,23085,23086,23087,23088,23089,23090,23091,23092,23093,23094,23095,23096,23097,23098,23099,23100,23101,23102,23103,23104,23105,23106,23107,23108,23109,23110,23111,23112,23113,23114,23115,23116,23117,23118,23119,23120,23121,23122,23123,23124,23125,23126,23127,23128,23129,23130,23131,23132,23133,23134,23135,23136,23137,23138,23139,23140,23141,23142,23143,23144,23145,23146,23147,23148,23149,23150,23151,23152,23153,23154,23155,23156,23157,23158,23159,23160,23161,23162,23163,23164,23165,23166,23167,23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,23183,23184,23185,23186,23187,23188,23189,23190,23191,23192,23193,23194,23195,23196,23197,23198,23199,23200,23201,23202,23203,23204,23205,23206,23207,23208,23209,23210,23211,23212,23213,23214,23215,23216,23217,23218,23219,23220,23221,23222,23223,23224,23225,23226,23227,23228,23229,23230,23231,23232,23233,23234,23235,23236,23237,23238,23239,23240,23241,23242,23243,23244,23245,23246,23247,23248,23249,23250,23251,23252,23253,23254,23255,23256,23257,23258,23259,23260,23261,23262,23263,23264,23265,23266,23267,23268,23269,23270,23271,23272,23273,23274,23275,23276,23277,23278,23279,23280,23281,23282,23283,23284,23285,23286,23287,23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,23300,23301,23302,23303,23304,23305,23306,23307,23308,23309,23310,23311,23312,23313,23314,23315,23316,23317,23318,23319,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23346,23347,23348,23349,23350,23351,23352,23353,23354,23355,23356,23357,23358,23359,23360,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,23372,23373,23374,23375,23376,23377,23378,23379,23380,23381,23382,23383,23384,23385,23386,23387,23388,23389,23390,23391,23392,23393,23394,23395,23396,23397,23398,23399,23400,23401,23402,23403,23404,23405,23406,23407,23408,23409,23410,23411,23412,23413,23414,23415,23416,23417,23418,23419,23420,23421,23422,23423,23424,23425,23426,23427,23428,23429,23430,23431,23432,23433,23434,23435,23436,23437,23438,23439,23440,23441,23442,23443,23444,23445,23446,23447,23448,23449,23450,23451,23452,23453,23454,23455,23456,23457,23458,23459,23460,23461,23462,23463,23464,23465,23466,23467,23468,23469,23470,23471,23472,23473,23474,23475,23476,23477,23478,23479,23480,23481,23482,23483,23484,23485,23486,23487,23488,23489,23490,23491,23492,23493,23494,23495,23496,23497,23498,23499,23500,23501,23502,23503,23504,23505,23506,23507,23508,23509,23510,23511,23512,23513,23514,23515,23516,23517,23518,23519,23520,23521,23522,23523,23524,23525,23526,23527,23528,23529,23530,23531,23532,23533,23534,23535,23536,23537,23538,23539,23540,23541,23542,23543,23544,23545,23546,23547,23548,23549,23550,23551,23552,23553,23554,23555,23556,23557,23558,23559,23560,23561,23562,23563,23564,23565,23566,23567,23568,23569,23570,23571,23572,23573,23574,23575,23576,23577,23578,23579,23580,23581,23582,23583,23584,23585,23586,23587,23588,23589,23590,23591,23592,23593,23594,23595,23596,23597,23598,23599,23600,23601,23602,23603,23604,23605,23606,23607,23608,23609,23610,23611,23612,23613,23614,23615,23616,23617,23618,23619,23620,23621,23622,23623,23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23638,23639,23640,23641,23642,23643,23644,23645,23646,23647,23648,23649,23650,23651,23652,23653,23654,23655,23656,23657,23658,23659,23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23671,23672,23673,23674,23675,23676,23677,23678,23679,23680,23681,23682,23683,23684,23685,23686,23687,23688,23689,23690,23691,23692,23693,23694,23695,23696,23697,23698,23699,23700,23701,23702,23703,23704,23705,23706,23707,23708,23709,23710,23711,23712,23713,23714,23715,23716,23717,23718,23719,23720,23721,23722,23723,23724,23725,23726,23727,23728,23729,23730,23731,23732,23733,23734,23735,23736,23737,23738,23739,23740,23741,23742,23743,23744,23745,23746,23747,23748,23749,23750,23751,23752,23753,23754,23755,23756,23757,23758,23759,23760,23761,23762,23763,23764,23765,23766,23767,23768,23769,23770,23771,23772,23773,23774,23775,23776,23777,23778,23779,23780,23781,23782,23783,23784,23785,23786,23787,23788,23789,23790,23791,23792,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23803,23804,23805,23806,23807,23808,23809,23810,23811,23812,23813,23814,23815,23816,23817,23818,23819,23820,23821,23822,23823,23824,23825,23826,23827,23828,23829,23830,23831,23832,23833,23834,23835,23836,23837,23838,23839,23840,23841,23842,23843,23844,23845,23846,23847,23848,23849,23850,23851,23852,23853,23854,23855,23856,23857,23858,23859,23860,23861,23862,23863,23864,23865,23866,23867,23868,23869,23870,23871,23872,23873,23874,23875,23876,23877,23878,23879,23880,23881,23882,23883,23884,23885,23886,23887,23888,23889,23890,23891,23892,23893,23894,23895,23896,23897,23898,23899,23900,23901,23902,23903,23904,23905,23906,23907,23908,23909,23910,23911,23912,23913,23914,23915,23916,23917,23918,23919,23920,23921,23922,23923,23924,23925,23926,23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23938,23939,23940,23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,23954,23955,23956,23957,23958,23959,23960,23961,23962,23963,23964,23965,23966,23967,23968,23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,23984,23985,23986,23987,23988,23989,23990,23991,23992,23993,23994,23995,23996,23997,23998,23999,24000,24001,24002,24003,24004,24005,24006,24007,24008,24009,24010,24011,24012,24013,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,24024,24025,24026,24027,24028,24029,24030,24031,24032,24033,24034,24035,24036,24037,24038,24039,24040,24041,24042,24043,24044,24045,24046,24047,24048,24049,24050,24051,24052,24053,24054,24055,24056,24057,24058,24059,24060,24061,24062,24063,24064,24065,24066,24067,24068,24069,24070,24071,24072,24073,24074,24075,24076,24077,24078,24079,24080,24081,24082,24083,24084,24085,24086,24087,24088,24089,24090,24091,24092,24093,24094,24095,24096,24097,24098,24099,24100,24101,24102,24103,24104,24105,24106,24107,24108,24109,24110,24111,24112,24113,24114,24115,24116,24117,24118,24119,24120,24121,24122,24123,24124,24125,24126,24127,24128,24129,24130,24131,24132,24133,24134,24135,24136,24137,24138,24139,24140,24141,24142,24143,24144,24145,24146,24147,24148,24149,24150,24151,24152,24153,24154,24155,24156,24157,24158,24159,24160,24161,24162,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,24174,24175,24176,24177,24178,24179,24180,24181,24182,24183,24184,24185,24186,24187,24188,24189,24190,24191,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,24203,24204,24205,24206,24207,24208,24209,24210,24211,24212,24213,24214,24215,24216,24217,24218,24219,24220,24221,24222,24223,24224,24225,24226,24227,24228,24229,24230,24231,24232,24233,24234,24235,24236,24237,24238,24239,24240,24241,24242,24243,24244,24245,24246,24247,24248,24249,24250,24251,24252,24253,24254,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24265,24266,24267,24268,24269,24270,24271,24272,24273,24274,24275,24276,24277,24278,24279,24280,24281,24282,24283,24284,24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,24308,24309,24310,24311,24312,24313,24314,24315,24316,24317,24318,24319,24320,24321,24322,24323,24324,24325,24326,24327,24328,24329,24330,24331,24332,24333,24334,24335,24336,24337,24338,24339,24340,24341,24342,24343,24344,24345,24346,24347,24348,24349,24350,24351,24352,24353,24354,24355,24356,24357,24358,24359,24360,24361,24362,24363,24364,24365,24366,24367,24368,24369,24370,24371,24372,24373,24374,24375,24376,24377,24378,24379,24380,24381,24382,24383,24384,24385,24386,24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,24400,24401,24402,24403,24404,24405,24406,24407,24408,24409,24410,24411,24412,24413,24414,24415,24416,24417,24418,24419,24420,24421,24422,24423,24424,24425,24426,24427,24428,24429,24430,24431,24432,24433,24434,24435,24436,24437,24438,24439,24440,24441,24442,24443,24444,24445,24446,24447,24448,24449,24450,24451,24452,24453,24454,24455,24456,24457,24458,24459,24460,24461,24462,24463,24464,24465,24466,24467,24468,24469,24470,24471,24472,24473,24474,24475,24476,24477,24478,24479,24480,24481,24482,24483,24484,24485,24486,24487,24488,24489,24490,24491,24492,24493,24494,24495,24496,24497,24498,24499,24500,24501,24502,24503,24504,24505,24506,24507,24508,24509,24510,24511,24512,24513,24514,24515,24516,24517,24518,24519,24520,24521,24522,24523,24524,24525,24526,24527,24528,24529,24530,24531,24532,24533,24534,24535,24536,24537,24538,24539,24540,24541,24542,24543,24544,24545,24546,24547,24548,24549,24550,24551,24552,24553,24554,24555,24556,24557,24558,24559,24560,24561,24562,24563,24564,24565,24566,24567,24568,24569,24570,24571,24572,24573,24574,24575,24576,24577,24578,24579,24580,24581,24582,24583,24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,25139,25140,25141,25142,25143,25144,25145,25146,25147,25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25159,25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25173,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,25283,25284,25285,25286,25287,25288,25289,25290,25291,25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,25403,25404,25405,25406,25407,25408,25409,25410,25411,25412,25413,25414,25415,25416,25417,25418,25419,25420,25421,25422,25423,25424,25425,25426,25427,25428,25429,25430,25431,25432,25433,25434,25435,25436,25437,25438,25439,25440,25441,25442,25443,25444,25445,25446,25447,25448,25449,25450,25451,25452,25453,25454,25455,25456,25457,25458,25459,25460,25461,25462,25463,25464,25465,25466,25467,25468,25469,25470,25471,25472,25473,25474,25475,25476,25477,25478,25479,25480,25481,25482,25483,25484,25485,25486,25487,25488,25489,25490,25491,25492,25493,25494,25495,25496,25497,25498,25499,25500,25501,25502,25503,25504,25505,25506,25507,25508,25509,25510,25511,25512,25513,25514,25515,25516,25517,25518,25519,25520,25521,25522,25523,25524,25525,25526,25527,25528,25529,25530,25531,25532,25533,25534,25535,25536,25537,25538,25539,25540,25541,25542,25543,25544,25545,25546,25547,25548,25549,25550,25551,25552,25553,25554,25555,25556,25557,25558,25559,25560,25561,25562,25563,25564,25565,25566,25567,25568,25569,25570,25571,25572,25573,25574,25575,25576,25577,25578,25579,25580,25581,25582,25583,25584,25585,25586,25587,25588,25589,25590,25591,25592,25593,25594,25595,25596,25597,25598,25599,25600,25601,25602,25603,25604,25605,25606,25607,25608,25609,25610,25611,25612,25613,25614,25615,25616,25617,25618,25619,25620,25621,25622,25623,25624,25625,25626,25627,25628,25629,25630,25631,25632,25633,25634,25635,25636,25637,25638,25639,25640,25641,25642,25643,25644,25645,25646,25647,25648,25649,25650,25651,25652,25653,25654,25655,25656,25657,25658,25659,25660,25661,25662,25663,25664,25665,25666,25667,25668,25669,25670,25671,25672,25673,25674,25675,25676,25677,25678,25679,25680,25681,25682,25683,25684,25685,25686,25687,25688,25689,25690,25691,25692,25693,25694,25695,25696,25697,25698,25699,25700,25701,25702,25703,25704,25705,25706,25707,25708,25709,25710,25711,25712,25713,25714,25715,25716,25717,25718,25719,25720,25721,25722,25723,25724,25725,25726,25727,25728,25729,25730,25731,25732,25733,25734,25735,25736,25737,25738,25739,25740,25741,25742,25743,25744,25745,25746,25747,25748,25749,25750,25751,25752,25753,25754,25755,25756,25757,25758,25759,25760,25761,25762,25763,25764,25765,25766,25767,25768,25769,25770,25771,25772,25773,25774,25775,25776,25777,25778,25779,25780,25781,25782,25783,25784,25785,25786,25787,25788,25789,25790,25791,25792,25793,25794,25795,25796,25797,25798,25799,25800,25801,25802,25803,25804,25805,25806,25807,25808,25809,25810,25811,25812,25813,25814,25815,25816,25817,25818,25819,25820,25821,25822,25823,25824,25825,25826,25827,25828,25829,25830,25831,25832,25833,25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,25847,25848,25849,25850,25851,25852,25853,25854,25855,25856,25857,25858,25859,25860,25861,25862,25863,25864,25865,25866,25867,25868,25869,25870,25871,25872,25873,25874,25875,25876,25877,25878,25879,25880,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,25891,25892,25893,25894,25895,25896,25897,25898,25899,25900,25901,25902,25903,25904,25905,25906,25907,25908,25909,25910,25911,25912,25913,25914,25915,25916,25917,25918,25919,25920,25921,25922,25923,25924,25925,25926,25927,25928,25929,25930,25931,25932,25933,25934,25935,25936,25937,25938,25939,25940,25941,25942,25943,25944,25945,25946,25947,25948,25949,25950,25951,25952,25953,25954,25955,25956,25957,25958,25959,25960,25961,25962,25963,25964,25965,25966,25967,25968,25969,25970,25971,25972,25973,25974,25975,25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,25988,25989,25990,25991,25992,25993,25994,25995,25996,25997,25998,25999,26000,26001,26002,26003,26004,26005,26006,26007,26008,26009,26010,26011,26012,26013,26014,26015,26016,26017,26018,26019,26020,26021,26022,26023,26024,26025,26026,26027,26028,26029,26030,26031,26032,26033,26034,26035,26036,26037,26038,26039,26040,26041,26042,26043,26044,26045,26046,26047,26048,26049,26050,26051,26052,26053,26054,26055,26056,26057,26058,26059,26060,26061,26062,26063,26064,26065,26066,26067,26068,26069,26070,26071,26072,26073,26074,26075,26076,26077,26078,26079,26080,26081,26082,26083,26084,26085,26086,26087,26088,26089,26090,26091,26092,26093,26094,26095,26096,26097,26098,26099,26100,26101,26102,26103,26104,26105,26106,26107,26108,26109,26110,26111,26112,26113,26114,26115,26116,26117,26118,26119,26120,26121,26122,26123,26124,26125,26126,26127,26128,26129,26130,26131,26132,26133,26134,26135,26136,26137,26138,26139,26140,26141,26142,26143,26144,26145,26146,26147,26148,26149,26150,26151,26152,26153,26154,26155,26156,26157,26158,26159,26160,26161,26162,26163,26164,26165,26166,26167,26168,26169,26170,26171,26172,26173,26174,26175,26176,26177,26178,26179,26180,26181,26182,26183,26184,26185,26186,26187,26188,26189,26190,26191,26192,26193,26194,26195,26196,26197,26198,26199,26200,26201,26202,26203,26204,26205,26206,26207,26208,26209,26210,26211,26212,26213,26214,26215,26216,26217,26218,26219,26220,26221,26222,26223,26224,26225,26226,26227,26228,26229,26230,26231,26232,26233,26234,26235,26236,26237,26238,26239,26240,26241,26242,26243,26244,26245,26246,26247,26248,26249,26250,26251,26252,26253,26254,26255,26256,26257,26258,26259,26260,26261,26262,26263,26264,26265,26266,26267,26268,26269,26270,26271,26272,26273,26274,26275,26276,26277,26278,26279,26280,26281,26282,26283,26284,26285,26286,26287,26288,26289,26290,26291,26292,26293,26294,26295,26296,26297,26298,26299,26300,26301,26302,26303,26304,26305,26306,26307,26308,26309,26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,26323,26324,26325,26326,26327,26328,26329,26330,26331,26332,26333,26334,26335,26336,26337,26338,26339,26340,26341,26342,26343,26344,26345,26346,26347,26348,26349,26350,26351,26352,26353,26354,26355,26356,26357,26358,26359,26360,26361,26362,26363,26364,26365,26366,26367,26368,26369,26370,26371,26372,26373,26374,26375,26376,26377,26378,26379,26380,26381,26382,26383,26384,26385,26386,26387,26388,26389,26390,26391,26392,26393,26394,26395,26396,26397,26398,26399,26400,26401,26402,26403,26404,26405,26406,26407,26408,26409,26410,26411,26412,26413,26414,26415,26416,26417,26418,26419,26420,26421,26422,26423,26424,26425,26426,26427,26428,26429,26430,26431,26432,26433,26434,26435,26436,26437,26438,26439,26440,26441,26442,26443,26444,26445,26446,26447,26448,26449,26450,26451,26452,26453,26454,26455,26456,26457,26458,26459,26460,26461,26462,26463,26464,26465,26466,26467,26468,26469,26470,26471,26472,26473,26474,26475,26476,26477,26478,26479,26480,26481,26482,26483,26484,26485,26486,26487,26488,26489,26490,26491,26492,26493,26494,26495,26496,26497,26498,26499,26500,26501,26502,26503,26504,26505,26506,26507,26508,26509,26510,26511,26512,26513,26514,26515,26516,26517,26518,26519,26520,26521,26522,26523,26524,26525,26526,26527,26528,26529,26530,26531,26532,26533,26534,26535,26536,26537,26538,26539,26540,26541,26542,26543,26544,26545,26546,26547,26548,26549,26550,26551,26552,26553,26554,26555,26556,26557,26558,26559,26560,26561,26562,26563,26564,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26575,26576,26577,26578,26579,26580,26581,26582,26583,26584,26585,26586,26587,26588,26589,26590,26591,26592,26593,26594,26595,26596,26597,26598,26599,26600,26601,26602,26603,26604,26605,26606,26607,26608,26609,26610,26611,26612,26613,26614,26615,26616,26617,26618,26619,26620,26621,26622,26623,26624,26625,26626,26627,26628,26629,26630,26631,26632,26633,26634,26635,26636,26637,26638,26639,26640,26641,26642,26643,26644,26645,26646,26647,26648,26649,26650,26651,26652,26653,26654,26655,26656,26657,26658,26659,26660,26661,26662,26663,26664,26665,26666,26667,26668,26669,26670,26671,26672,26673,26674,26675,26676,26677,26678,26679,26680,26681,26682,26683,26684,26685,26686,26687,26688,26689,26690,26691,26692,26693,26694,26695,26696,26697,26698,26699,26700,26701,26702,26703,26704,26705,26706,26707,26708,26709,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,26720,26721,26722,26723,26724,26725,26726,26727,26728,26729,26730,26731,26732,26733,26734,26735,26736,26737,26738,26739,26740,26741,26742,26743,26744,26745,26746,26747,26748,26749,26750,26751,26752,26753,26754,26755,26756,26757,26758,26759,26760,26761,26762,26763,26764,26765,26766,26767,26768,26769,26770,26771,26772,26773,26774,26775,26776,26777,26778,26779,26780,26781,26782,26783,26784,26785,26786,26787,26788,26789,26790,26791,26792,26793,26794,26795,26796,26797,26798,26799,26800,26801,26802,26803,26804,26805,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,26816,26817,26818,26819,26820,26821,26822,26823,26824,26825,26826,26827,26828,26829,26830,26831,26832,26833,26834,26835,26836,26837,26838,26839,26840,26841,26842,26843,26844,26845,26846,26847,26848,26849,26850,26851,26852,26853,26854,26855,26856,26857,26858,26859,26860,26861,26862,26863,26864,26865,26866,26867,26868,26869,26870,26871,26872,26873,26874,26875,26876,26877,26878,26879,26880,26881,26882,26883,26884,26885,26886,26887,26888,26889,26890,26891,26892,26893,26894,26895,26896,26897,26898,26899,26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,26910,26911,26912,26913,26914,26915,26916,26917,26918,26919,26920,26921,26922,26923,26924,26925,26926,26927,26928,26929,26930,26931,26932,26933,26934,26935,26936,26937,26938,26939,26940,26941,26942,26943,26944,26945,26946,26947,26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,26959,26960,26961,26962,26963,26964,26965,26966,26967,26968,26969,26970,26971,26972,26973,26974,26975,26976,26977,26978,26979,26980,26981,26982,26983,26984,26985,26986,26987,26988,26989,26990,26991,26992,26993,26994,26995,26996,26997,26998,26999,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015,27016,27017,27018,27019,27020,27021,27022,27023,27024,27025,27026,27027,27028,27029,27030,27031,27032,27033,27034,27035,27036,27037,27038,27039,27040,27041,27042,27043,27044,27045,27046,27047,27048,27049,27050,27051,27052,27053,27054,27055,27056,27057,27058,27059,27060,27061,27062,27063,27064,27065,27066,27067,27068,27069,27070,27071,27072,27073,27074,27075,27076,27077,27078,27079,27080,27081,27082,27083,27084,27085,27086,27087,27088,27089,27090,27091,27092,27093,27094,27095,27096,27097,27098,27099,27100,27101,27102,27103,27104,27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27117,27118,27119,27120,27121,27122,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,27133,27134,27135,27136,27137,27138,27139,27140,27141,27142,27143,27144,27145,27146,27147,27148,27149,27150,27151,27152,27153,27154,27155,27156,27157,27158,27159,27160,27161,27162,27163,27164,27165,27166,27167,27168,27169,27170,27171,27172,27173,27174,27175,27176,27177,27178,27179,27180,27181,27182,27183,27184,27185,27186,27187,27188,27189,27190,27191,27192,27193,27194,27195,27196,27197,27198,27199,27200,27201,27202,27203,27204,27205,27206,27207,27208,27209,27210,27211,27212,27213,27214,27215,27216,27217,27218,27219,27220,27221,27222,27223,27224,27225,27226,27227,27228,27229,27230,27231,27232,27233,27234,27235,27236,27237,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,27248,27249,27250,27251,27252,27253,27254,27255,27256,27257,27258,27259,27260,27261,27262,27263,27264,27265,27266,27267,27268,27269,27270,27271,27272,27273,27274,27275,27276,27277,27278,27279,27280,27281,27282,27283,27284,27285,27286,27287,27288,27289,27290,27291,27292,27293,27294,27295,27296,27297,27298,27299,27300,27301,27302,27303,27304,27305,27306,27307,27308,27309,27310,27311,27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,27324,27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,27416,27417,27418,27419,27420,27421,27422,27423,27424,27425,27426,27427,27428,27429,27430,27431,27432,27433,27434,27435,27436,27437,27438,27439,27440,27441,27442,27443,27444,27445,27446,27447,27448,27449,27450,27451,27452,27453,27454,27455,27456,27457,27458,27459,27460,27461,27462,27463,27464,27465,27466,27467,27468,27469,27470,27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27481,27482,27483,27484,27485,27486,27487,27488,27489,27490,27491,27492,27493,27494,27495,27496,27497,27498,27499,27500,27501,27502,27503,27504,27505,27506,27507,27508,27509,27510,27511,27512,27513,27514,27515,27516,27517,27518,27519,27520,27521,27522,27523,27524,27525,27526,27527,27528,27529,27530,27531,27532,27533,27534,27535,27536,27537,27538,27539,27540,27541,27542,27543,27544,27545,27546,27547,27548,27549,27550,27551,27552,27553,27554,27555,27556,27557,27558,27559,27560,27561,27562,27563,27564,27565,27566,27567,27568,27569,27570,27571,27572,27573,27574,27575,27576,27577,27578,27579,27580,27581,27582,27583,27584,27585,27586,27587,27588,27589,27590,27591,27592,27593,27594,27595,27596,27597,27598,27599,27600,27601,27602,27603,27604,27605,27606,27607,27608,27609,27610,27611,27612,27613,27614,27615,27616,27617,27618,27619,27620,27621,27622,27623,27624,27625,27626,27627,27628,27629,27630,27631,27632,27633,27634,27635,27636,27637,27638,27639,27640,27641,27642,27643,27644,27645,27646,27647,27648,27649,27650,27651,27652,27653,27654,27655,27656,27657,27658,27659,27660,27661,27662,27663,27664,27665,27666,27667,27668,27669,27670,27671,27672,27673,27674,27675,27676,27677,27678,27679,27680,27681,27682,27683,27684,27685,27686,27687,27688,27689,27690,27691,27692,27693,27694,27695,27696,27697,27698,27699,27700,27701,27702,27703,27704,27705,27706,27707,27708,27709,27710,27711,27712,27713,27714,27715,27716,27717,27718,27719,27720,27721,27722,27723,27724,27725,27726,27727,27728,27729,27730,27731,27732,27733,27734,27735,27736,27737,27738,27739,27740,27741,27742,27743,27744,27745,27746,27747,27748,27749,27750,27751,27752,27753,27754,27755,27756,27757,27758,27759,27760,27761,27762,27763,27764,27765,27766,27767,27768,27769,27770,27771,27772,27773,27774,27775,27776,27777,27778,27779,27780,27781,27782,27783,27784,27785,27786,27787,27788,27789,27790,27791,27792,27793,27794,27795,27796,27797,27798,27799,27800,27801,27802,27803,27804,27805,27806,27807,27808,27809,27810,27811,27812,27813,27814,27815,27816,27817,27818,27819,27820,27821,27822,27823,27824,27825,27826,27827,27828,27829,27830,27831,27832,27833,27834,27835,27836,27837,27838,27839,27840,27841,27842,27843,27844,27845,27846,27847,27848,27849,27850,27851,27852,27853,27854,27855,27856,27857,27858,27859,27860,27861,27862,27863,27864,27865,27866,27867,27868,27869,27870,27871,27872,27873,27874,27875,27876,27877,27878,27879,27880,27881,27882,27883,27884,27885,27886,27887,27888,27889,27890,27891,27892,27893,27894,27895,27896,27897,27898,27899,27900,27901,27902,27903,27904,27905,27906,27907,27908,27909,27910,27911,27912,27913,27914,27915,27916,27917,27918,27919,27920,27921,27922,27923,27924,27925,27926,27927,27928,27929,27930,27931,27932,27933,27934,27935,27936,27937,27938,27939,27940,27941,27942,27943,27944,27945,27946,27947,27948,27949,27950,27951,27952,27953,27954,27955,27956,27957,27958,27959,27960,27961,27962,27963,27964,27965,27966,27967,27968,27969,27970,27971,27972,27973,27974,27975,27976,27977,27978,27979,27980,27981,27982,27983,27984,27985,27986,27987,27988,27989,27990,27991,27992,27993,27994,27995,27996,27997,27998,27999,28000,28001,28002,28003,28004,28005,28006,28007,28008,28009,28010,28011,28012,28013,28014,28015,28016,28017,28018,28019,28020,28021,28022,28023,28024,28025,28026,28027,28028,28029,28030,28031,28032,28033,28034,28035,28036,28037,28038,28039,28040,28041,28042,28043,28044,28045,28046,28047,28048,28049,28050,28051,28052,28053,28054,28055,28056,28057,28058,28059,28060,28061,28062,28063,28064,28065,28066,28067,28068,28069,28070,28071,28072,28073,28074,28075,28076,28077,28078,28079,28080,28081,28082,28083,28084,28085,28086,28087,28088,28089,28090,28091,28092,28093,28094,28095,28096,28097,28098,28099,28100,28101,28102,28103,28104,28105,28106,28107,28108,28109,28110,28111,28112,28113,28114,28115,28116,28117,28118,28119,28120,28121,28122,28123,28124,28125,28126,28127,28128,28129,28130,28131,28132,28133,28134,28135,28136,28137,28138,28139,28140,28141,28142,28143,28144,28145,28146,28147,28148,28149,28150,28151,28152,28153,28154,28155,28156,28157,28158,28159,28160,28161,28162,28163,28164,28165,28166,28167,28168,28169,28170,28171,28172,28173,28174,28175,28176,28177,28178,28179,28180,28181,28182,28183,28184,28185,28186,28187,28188,28189,28190,28191,28192,28193,28194,28195,28196,28197,28198,28199,28200,28201,28202,28203,28204,28205,28206,28207,28208,28209,28210,28211,28212,28213,28214,28215,28216,28217,28218,28219,28220,28221,28222,28223,28224,28225,28226,28227,28228,28229,28230,28231,28232,28233,28234,28235,28236,28237,28238,28239,28240,28241,28242,28243,28244,28245,28246,28247,28248,28249,28250,28251,28252,28253,28254,28255,28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28267,28268,28269,28270,28271,28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284,28285,28286,28287,28288,28289,28290,28291,28292,28293,28294,28295,28296,28297,28298,28299,28300,28301,28302,28303,28304,28305,28306,28307,28308,28309,28310,28311,28312,28313,28314,28315,28316,28317,28318,28319,28320,28321,28322,28323,28324,28325,28326,28327,28328,28329,28330,28331,28332,28333,28334,28335,28336,28337,28338,28339,28340,28341,28342,28343,28344,28345,28346,28347,28348,28349,28350,28351,28352,28353,28354,28355,28356,28357,28358,28359,28360,28361,28362,28363,28364,28365,28366,28367,28368,28369,28370,28371,28372,28373,28374,28375,28376,28377,28378,28379,28380,28381,28382,28383,28384,28385,28386,28387,28388,28389,28390,28391,28392,28393,28394,28395,28396,28397,28398,28399,28400,28401,28402,28403,28404,28405,28406,28407,28408,28409,28410,28411,28412,28413,28414,28415,28416,28417,28418,28419,28420,28421,28422,28423,28424,28425,28426,28427,28428,28429,28430,28431,28432,28433,28434,28435,28436,28437,28438,28439,28440,28441,28442,28443,28444,28445,28446,28447,28448,28449,28450,28451,28452,28453,28454,28455,28456,28457,28458,28459,28460,28461,28462,28463,28464,28465,28466,28467,28468,28469,28470,28471,28472,28473,28474,28475,28476,28477,28478,28479,28480,28481,28482,28483,28484,28485,28486,28487,28488,28489,28490,28491,28492,28493,28494,28495,28496,28497,28498,28499,28500,28501,28502,28503,28504,28505,28506,28507,28508,28509,28510,28511,28512,28513,28514,28515,28516,28517,28518,28519,28520,28521,28522,28523,28524,28525,28526,28527,28528,28529,28530,28531,28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,28544,28545,28546,28547,28548,28549,28550,28551,28552,28553,28554,28555,28556,28557,28558,28559,28560,28561,28562,28563,28564,28565,28566,28567,28568,28569,28570,28571,28572,28573,28574,28575,28576,28577,28578,28579,28580,28581,28582,28583,28584,28585,28586,28587,28588,28589,28590,28591,28592,28593,28594,28595,28596,28597,28598,28599,28600,28601,28602,28603,28604,28605,28606,28607,28608,28609,28610,28611,28612,28613,28614,28615,28616,28617,28618,28619,28620,28621,28622,28623,28624,28625,28626,28627,28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,28638,28639,28640,28641,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,28652,28653,28654,28655,28656,28657,28658,28659,28660,28661,28662,28663,28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675,28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687,28688,28689,28690,28691,28692,28693,28694,28695,28696,28697,28698,28699,28700,28701,28702,28703,28704,28705,28706,28707,28708,28709,28710,28711,28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,28725,28726,28727,28728,28729,28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,28747,28748,28749,28750,28751,28752,28753,28754,28755,28756,28757,28758,28759,28760,28761,28762,28763,28764,28765,28766,28767,28768,28769,28770,28771,28772,28773,28774,28775,28776,28777,28778,28779,28780,28781,28782,28783,28784,28785,28786,28787,28788,28789,28790,28791,28792,28793,28794,28795,28796,28797,28798,28799,28800,28801,28802,28803,28804,28805,28806,28807,28808,28809,28810,28811,28812,28813,28814,28815,28816,28817,28818,28819,28820,28821,28822,28823,28824,28825,28826,28827,28828,28829,28830,28831,28832,28833,28834,28835,28836,28837,28838,28839,28840,28841,28842,28843,28844,28845,28846,28847,28848,28849,28850,28851,28852,28853,28854,28855,28856,28857,28858,28859,28860,28861,28862,28863,28864,28865,28866,28867,28868,28869,28870,28871,28872,28873,28874,28875,28876,28877,28878,28879,28880,28881,28882,28883,28884,28885,28886,28887,28888,28889,28890,28891,28892,28893,28894,28895,28896,28897,28898,28899,28900,28901,28902,28903,28904,28905,28906,28907,28908,28909,28910,28911,28912,28913,28914,28915,28916,28917,28918,28919,28920,28921,28922,28923,28924,28925,28926,28927,28928,28929,28930,28931,28932,28933,28934,28935,28936,28937,28938,28939,28940,28941,28942,28943,28944,28945,28946,28947,28948,28949,28950,28951,28952,28953,28954,28955,28956,28957,28958,28959,28960,28961,28962,28963,28964,28965,28966,28967,28968,28969,28970,28971,28972,28973,28974,28975,28976,28977,28978,28979,28980,28981,28982,28983,28984,28985,28986,28987,28988,28989,28990,28991,28992,28993,28994,28995,28996,28997,28998,28999,29000,29001,29002,29003,29004,29005,29006,29007,29008,29009,29010,29011,29012,29013,29014,29015,29016,29017,29018,29019,29020,29021,29022,29023,29024,29025,29026,29027,29028,29029,29030,29031,29032,29033,29034,29035,29036,29037,29038,29039,29040,29041,29042,29043,29044,29045,29046,29047,29048,29049,29050,29051,29052,29053,29054,29055,29056,29057,29058,29059,29060,29061,29062,29063,29064,29065,29066,29067,29068,29069,29070,29071,29072,29073,29074,29075,29076,29077,29078,29079,29080,29081,29082,29083,29084,29085,29086,29087,29088,29089,29090,29091,29092,29093,29094,29095,29096,29097,29098,29099,29100,29101,29102,29103,29104,29105,29106,29107,29108,29109,29110,29111,29112,29113,29114,29115,29116,29117,29118,29119,29120,29121,29122,29123,29124,29125,29126,29127,29128,29129,29130,29131,29132,29133,29134,29135,29136,29137,29138,29139,29140,29141,29142,29143,29144,29145,29146,29147,29148,29149,29150,29151,29152,29153,29154,29155,29156,29157,29158,29159,29160,29161,29162,29163,29164,29165,29166,29167,29168,29169,29170,29171,29172,29173,29174,29175,29176,29177,29178,29179,29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29190,29191,29192,29193,29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,29204,29205,29206,29207,29208,29209,29210,29211,29212,29213,29214,29215,29216,29217,29218,29219,29220,29221,29222,29223,29224,29225,29226,29227,29228,29229,29230,29231,29232,29233,29234,29235,29236,29237,29238,29239,29240,29241,29242,29243,29244,29245,29246,29247,29248,29249,29250,29251,29252,29253,29254,29255,29256,29257,29258,29259,29260,29261,29262,29263,29264,29265,29266,29267,29268,29269,29270,29271,29272,29273,29274,29275,29276,29277,29278,29279,29280,29281,29282,29283,29284,29285,29286,29287,29288,29289,29290,29291,29292,29293,29294,29295,29296,29297,29298,29299,29300,29301,29302,29303,29304,29305,29306,29307,29308,29309,29310,29311,29312,29313,29314,29315,29316,29317,29318,29319,29320,29321,29322,29323,29324,29325,29326,29327,29328,29329,29330,29331,29332,29333,29334,29335,29336,29337,29338,29339,29340,29341,29342,29343,29344,29345,29346,29347,29348,29349,29350,29351,29352,29353,29354,29355,29356,29357,29358,29359,29360,29361,29362,29363,29364,29365,29366,29367,29368,29369,29370,29371,29372,29373,29374,29375,29376,29377,29378,29379,29380,29381,29382,29383,29384,29385,29386,29387,29388,29389,29390,29391,29392,29393,29394,29395,29396,29397,29398,29399,29400,29401,29402,29403,29404,29405,29406,29407,29408,29409,29410,29411,29412,29413,29414,29415,29416,29417,29418,29419,29420,29421,29422,29423,29424,29425,29426,29427,29428,29429,29430,29431,29432,29433,29434,29435,29436,29437,29438,29439,29440,29441,29442,29443,29444,29445,29446,29447,29448,29449,29450,29451,29452,29453,29454,29455,29456,29457,29458,29459,29460,29461,29462,29463,29464,29465,29466,29467,29468,29469,29470,29471,29472,29473,29474,29475,29476,29477,29478,29479,29480,29481,29482,29483,29484,29485,29486,29487,29488,29489,29490,29491,29492,29493,29494,29495,29496,29497,29498,29499,29500,29501,29502,29503,29504,29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,29516,29517,29518,29519,29520,29521,29522,29523,29524,29525,29526,29527,29528,29529,29530,29531,29532,29533,29534,29535,29536,29537,29538,29539,29540,29541,29542,29543,29544,29545,29546,29547,29548,29549,29550,29551,29552,29553,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563,29564,29565,29566,29567,29568,29569,29570,29571,29572,29573,29574,29575,29576,29577,29578,29579,29580,29581,29582,29583,29584,29585,29586,29587,29588,29589,29590,29591,29592,29593,29594,29595,29596,29597,29598,29599,29600,29601,29602,29603,29604,29605,29606,29607,29608,29609,29610,29611,29612,29613,29614,29615,29616,29617,29618,29619,29620,29621,29622,29623,29624,29625,29626,29627,29628,29629,29630,29631,29632,29633,29634,29635,29636,29637,29638,29639,29640,29641,29642,29643,29644,29645,29646,29647,29648,29649,29650,29651,29652,29653,29654,29655,29656,29657,29658,29659,29660,29661,29662,29663,29664,29665,29666,29667,29668,29669,29670,29671,29672,29673,29674,29675,29676,29677,29678,29679,29680,29681,29682,29683,29684,29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,29698,29699,29700,29701,29702,29703,29704,29705,29706,29707,29708,29709,29710,29711,29712,29713,29714,29715,29716,29717,29718,29719,29720,29721,29722,29723,29724,29725,29726,29727,29728,29729,29730,29731,29732,29733,29734,29735,29736,29737,29738,29739,29740,29741,29742,29743,29744,29745,29746,29747,29748,29749,29750,29751,29752,29753,29754,29755,29756,29757,29758,29759,29760,29761,29762,29763,29764,29765,29766,29767,29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,29779,29780,29781,29782,29783,29784,29785,29786,29787,29788,29789,29790,29791,29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,29805,29806,29807,29808,29809,29810,29811,29812,29813,29814,29815,29816,29817,29818,29819,29820,29821,29822,29823,29824,29825,29826,29827,29828,29829,29830,29831,29832,29833,29834,29835,29836,29837,29838,29839,29840,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,29852,29853,29854,29855,29856,29857,29858,29859,29860,29861,29862,29863,29864,29865,29866,29867,29868,29869,29870,29871,29872,29873,29874,29875,29876,29877,29878,29879,29880,29881,29882,29883,29884,29885,29886,29887,29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,29898,29899,29900,29901,29902,29903,29904,29905,29906,29907,29908,29909,29910,29911,29912,29913,29914,29915,29916,29917,29918,29919,29920,29921,29922,29923,29924,29925,29926,29927,29928,29929,29930,29931,29932,29933,29934,29935,29936,29937,29938,29939,29940,29941,29942,29943,29944,29945,29946,29947,29948,29949,29950,29951,29952,29953,29954,29955,29956,29957,29958,29959,29960,29961,29962,29963,29964,29965,29966,29967,29968,29969,29970,29971,29972,29973,29974,29975,29976,29977,29978,29979,29980,29981,29982,29983,29984,29985,29986,29987,29988,29989,29990,29991,29992,29993,29994,29995,29996,29997,29998,29999,30000,30001,30002,30003,30004,30005,30006,30007,30008,30009,30010,30011,30012,30013,30014,30015,30016,30017,30018,30019,30020,30021,30022,30023,30024,30025,30026,30027,30028,30029,30030,30031,30032,30033,30034,30035,30036,30037,30038,30039,30040,30041,30042,30043,30044,30045,30046,30047,30048,30049,30050,30051,30052,30053,30054,30055,30056,30057,30058,30059,30060,30061,30062,30063,30064,30065,30066,30067,30068,30069,30070,30071,30072,30073,30074,30075,30076,30077,30078,30079,30080,30081,30082,30083,30084,30085,30086,30087,30088,30089,30090,30091,30092,30093,30094,30095,30096,30097,30098,30099,30100,30101,30102,30103,30104,30105,30106,30107,30108,30109,30110,30111,30112,30113,30114,30115,30116,30117,30118,30119,30120,30121,30122,30123,30124,30125,30126,30127,30128,30129,30130,30131,30132,30133,30134,30135,30136,30137,30138,30139,30140,30141,30142,30143,30144,30145,30146,30147,30148,30149,30150,30151,30152,30153,30154,30155,30156,30157,30158,30159,30160,30161,30162,30163,30164,30165,30166,30167,30168,30169,30170,30171,30172,30173,30174,30175,30176,30177,30178,30179,30180,30181,30182,30183,30184,30185,30186,30187,30188,30189,30190,30191,30192,30193,30194,30195,30196,30197,30198,30199,30200,30201,30202,30203,30204,30205,30206,30207,30208,30209,30210,30211,30212,30213,30214,30215,30216,30217,30218,30219,30220,30221,30222,30223,30224,30225,30226,30227,30228,30229,30230,30231,30232,30233,30234,30235,30236,30237,30238,30239,30240,30241,30242,30243,30244,30245,30246,30247,30248,30249,30250,30251,30252,30253,30254,30255,30256,30257,30258,30259,30260,30261,30262,30263,30264,30265,30266,30267,30268,30269,30270,30271,30272,30273,30274,30275,30276,30277,30278,30279,30280,30281,30282,30283,30284,30285,30286,30287,30288,30289,30290,30291,30292,30293,30294,30295,30296,30297,30298,30299,30300,30301,30302,30303,30304,30305,30306,30307,30308,30309,30310,30311,30312,30313,30314,30315,30316,30317,30318,30319,30320,30321,30322,30323,30324,30325,30326,30327,30328,30329,30330,30331,30332,30333,30334,30335,30336,30337,30338,30339,30340,30341,30342,30343,30344,30345,30346,30347,30348,30349,30350,30351,30352,30353,30354,30355,30356,30357,30358,30359,30360,30361,30362,30363,30364,30365,30366,30367,30368,30369,30370,30371,30372,30373,30374,30375,30376,30377,30378,30379,30380,30381,30382,30383,30384,30385,30386,30387,30388,30389,30390,30391,30392,30393,30394,30395,30396,30397,30398,30399,30400,30401,30402,30403,30404,30405,30406,30407,30408,30409,30410,30411,30412,30413,30414,30415,30416,30417,30418,30419,30420,30421,30422,30423,30424,30425,30426,30427,30428,30429,30430,30431,30432,30433,30434,30435,30436,30437,30438,30439,30440,30441,30442,30443,30444,30445,30446,30447,30448,30449,30450,30451,30452,30453,30454,30455,30456,30457,30458,30459,30460,30461,30462,30463,30464,30465,30466,30467,30468,30469,30470,30471,30472,30473,30474,30475,30476,30477,30478,30479,30480,30481,30482,30483,30484,30485,30486,30487,30488,30489,30490,30491,30492,30493,30494,30495,30496,30497,30498,30499,30500,30501,30502,30503,30504,30505,30506,30507,30508,30509,30510,30511,30512,30513,30514,30515,30516,30517,30518,30519,30520,30521,30522,30523,30524,30525,30526,30527,30528,30529,30530,30531,30532,30533,30534,30535,30536,30537,30538,30539,30540,30541,30542,30543,30544,30545,30546,30547,30548,30549,30550,30551,30552,30553,30554,30555,30556,30557,30558,30559,30560,30561,30562,30563,30564,30565,30566,30567,30568,30569,30570,30571,30572,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,30584,30585,30586,30587,30588,30589,30590,30591,30592,30593,30594,30595,30596,30597,30598,30599,30600,30601,30602,30603,30604,30605,30606,30607,30608,30609,30610,30611,30612,30613,30614,30615,30616,30617,30618,30619,30620,30621,30622,30623,30624,30625,30626,30627,30628,30629,30630,30631,30632,30633,30634,30635,30636,30637,30638,30639,30640,30641,30642,30643,30644,30645,30646,30647,30648,30649,30650,30651,30652,30653,30654,30655,30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,30668,30669,30670,30671,30672,30673,30674,30675,30676,30677,30678,30679,30680,30681,30682,30683,30684,30685,30686,30687,30688,30689,30690,30691,30692,30693,30694,30695,30696,30697,30698,30699,30700,30701,30702,30703,30704,30705,30706,30707,30708,30709,30710,30711,30712,30713,30714,30715,30716,30717,30718,30719,30720,30721,30722,30723,30724,30725,30726,30727,30728,30729,30730,30731,30732,30733,30734,30735,30736,30737,30738,30739,30740,30741,30742,30743,30744,30745,30746,30747,30748,30749,30750,30751,30752,30753,30754,30755,30756,30757,30758,30759,30760,30761,30762,30763,30764,30765,30766,30767,30768,30769,30770,30771,30772,30773,30774,30775,30776,30777,30778,30779,30780,30781,30782,30783,30784,30785,30786,30787,30788,30789,30790,30791,30792,30793,30794,30795,30796,30797,30798,30799,30800,30801,30802,30803,30804,30805,30806,30807,30808,30809,30810,30811,30812,30813,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,30824,30825,30826,30827,30828,30829,30830,30831,30832,30833,30834,30835,30836,30837,30838,30839,30840,30841,30842,30843,30844,30845,30846,30847,30848,30849,30850,30851,30852,30853,30854,30855,30856,30857,30858,30859,30860,30861,30862,30863,30864,30865,30866,30867,30868,30869,30870,30871,30872,30873,30874,30875,30876,30877,30878,30879,30880,30881,30882,30883,30884,30885,30886,30887,30888,30889,30890,30891,30892,30893,30894,30895,30896,30897,30898,30899,30900,30901,30902,30903,30904,30905,30906,30907,30908,30909,30910,30911,30912,30913,30914,30915,30916,30917,30918,30919,30920,30921,30922,30923,30924,30925,30926,30927,30928,30929,30930,30931,30932,30933,30934,30935,30936,30937,30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,30948,30949,30950,30951,30952,30953,30954,30955,30956,30957,30958,30959,30960,30961,30962,30963,30964,30965,30966,30967,30968,30969,30970,30971,30972,30973,30974,30975,30976,30977,30978,30979,30980,30981,30982,30983,30984,30985,30986,30987,30988,30989,30990,30991,30992,30993,30994,30995,30996,30997,30998,30999,31000,31001,31002,31003,31004,31005,31006,31007,31008,31009,31010,31011,31012,31013,31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,31027,31028,31029,31030,31031,31032,31033,31034,31035,31036,31037,31038,31039,31040,31041,31042,31043,31044,31045,31046,31047,31048,31049,31050,31051,31052,31053,31054,31055,31056,31057,31058,31059,31060,31061,31062,31063,31064,31065,31066,31067,31068,31069,31070,31071,31072,31073,31074,31075,31076,31077,31078,31079,31080,31081,31082,31083,31084,31085,31086,31087,31088,31089,31090,31091,31092,31093,31094,31095,31096,31097,31098,31099,31100,31101,31102,31103,31104,31105,31106,31107,31108,31109,31110,31111,31112,31113,31114,31115,31116,31117,31118,31119,31120,31121,31122,31123,31124,31125,31126,31127,31128,31129,31130,31131,31132,31133,31134,31135,31136,31137,31138,31139,31140,31141,31142,31143,31144,31145,31146,31147,31148,31149,31150,31151,31152,31153,31154,31155,31156,31157,31158,31159,31160,31161,31162,31163,31164,31165,31166,31167,31168,31169,31170,31171,31172,31173,31174,31175,31176,31177,31178,31179,31180,31181,31182,31183,31184,31185,31186,31187,31188,31189,31190,31191,31192,31193,31194,31195,31196,31197,31198,31199,31200,31201,31202,31203,31204,31205,31206,31207,31208,31209,31210,31211,31212,31213,31214,31215,31216,31217,31218,31219,31220,31221,31222,31223,31224,31225,31226,31227,31228,31229,31230,31231,31232,31233,31234,31235,31236,31237,31238,31239,31240,31241,31242,31243,31244,31245,31246,31247,31248,31249,31250,31251,31252,31253,31254,31255,31256,31257,31258,31259,31260,31261,31262,31263,31264,31265,31266,31267,31268,31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,31292,31293,31294,31295,31296,31297,31298,31299,31300,31301,31302,31303,31304,31305,31306,31307,31308,31309,31310,31311,31312,31313,31314,31315,31316,31317,31318,31319,31320,31321,31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,31332,31333,31334,31335,31336,31337,31338,31339,31340,31341,31342,31343,31344,31345,31346,31347,31348,31349,31350,31351,31352,31353,31354,31355,31356,31357,31358,31359,31360,31361,31362,31363,31364,31365,31366,31367,31368,31369,31370,31371,31372,31373,31374,31375,31376,31377,31378,31379,31380,31381,31382,31383,31384,31385,31386,31387,31388,31389,31390,31391,31392,31393,31394,31395,31396,31397,31398,31399,31400,31401,31402,31403,31404,31405,31406,31407,31408,31409,31410,31411,31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31423,31424,31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31435,31436,31437,31438,31439,31440,31441,31442,31443,31444,31445,31446,31447,31448,31449,31450,31451,31452,31453,31454,31455,31456,31457,31458,31459,31460,31461,31462,31463,31464,31465,31466,31467,31468,31469,31470,31471,31472,31473,31474,31475,31476,31477,31478,31479,31480,31481,31482,31483,31484,31485,31486,31487,31488,31489,31490,31491,31492,31493,31494,31495,31496,31497,31498,31499,31500,31501,31502,31503,31504,31505,31506,31507,31508,31509,31510,31511,31512,31513,31514,31515,31516,31517,31518,31519,31520,31521,31522,31523,31524,31525,31526,31527,31528,31529,31530,31531,31532,31533,31534,31535,31536,31537,31538,31539,31540,31541,31542,31543,31544,31545,31546,31547,31548,31549,31550,31551,31552,31553,31554,31555,31556,31557,31558,31559,31560,31561,31562,31563,31564,31565,31566,31567,31568,31569,31570,31571,31572,31573,31574,31575,31576,31577,31578,31579,31580,31581,31582,31583,31584,31585,31586,31587,31588,31589,31590,31591,31592,31593,31594,31595,31596,31597,31598,31599,31600,31601,31602,31603,31604,31605,31606,31607,31608,31609,31610,31611,31612,31613,31614,31615,31616,31617,31618,31619,31620,31621,31622,31623,31624,31625,31626,31627,31628,31629,31630,31631,31632,31633,31634,31635,31636,31637,31638,31639,31640,31641,31642,31643,31644,31645,31646,31647,31648,31649,31650,31651,31652,31653,31654,31655,31656,31657,31658,31659,31660,31661,31662,31663,31664,31665,31666,31667,31668,31669,31670,31671,31672,31673,31674,31675,31676,31677,31678,31679,31680,31681,31682,31683,31684,31685,31686,31687,31688,31689,31690,31691,31692,31693,31694,31695,31696,31697,31698,31699,31700,31701,31702,31703,31704,31705,31706,31707,31708,31709,31710,31711,31712,31713,31714,31715,31716,31717,31718,31719,31720,31721,31722,31723,31724,31725,31726,31727,31728,31729,31730,31731,31732,31733,31734,31735,31736,31737,31738,31739,31740,31741,31742,31743,31744,31745,31746,31747,31748,31749,31750,31751,31752,31753,31754,31755,31756,31757,31758,31759,31760,31761,31762,31763,31764,31765,31766,31767,31768,31769,31770,31771,31772,31773,31774,31775,31776,31777,31778,31779,31780,31781,31782,31783,31784,31785,31786,31787,31788,31789,31790,31791,31792,31793,31794,31795,31796,31797,31798,31799,31800,31801,31802,31803,31804,31805,31806,31807,31808,31809,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31821,31822,31823,31824,31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,31836,31837,31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,31849,31850,31851,31852,31853,31854,31855,31856,31857,31858,31859,31860,31861,31862,31863,31864,31865,31866,31867,31868,31869,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,31880,31881,31882,31883,31884,31885,31886,31887,31888,31889,31890,31891,31892,31893,31894,31895,31896,31897,31898,31899,31900,31901,31902,31903,31904,31905,31906,31907,31908,31909,31910,31911,31912,31913,31914,31915,31916,31917,31918,31919,31920,31921,31922,31923,31924,31925,31926,31927,31928,31929,31930,31931,31932,31933,31934,31935,31936,31937,31938,31939,31940,31941,31942,31943,31944,31945,31946,31947,31948,31949,31950,31951,31952,31953,31954,31955,31956,31957,31958,31959,31960,31961,31962,31963,31964,31965,31966,31967,31968,31969,31970,31971,31972,31973,31974,31975,31976,31977,31978,31979,31980,31981,31982,31983,31984,31985,31986,31987,31988,31989,31990,31991,31992,31993,31994,31995,31996,31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,32010,32011,32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023,32024,32025,32026,32027,32028,32029,32030,32031,32032,32033,32034,32035,32036,32037,32038,32039,32040,32041,32042,32043,32044,32045,32046,32047,32048,32049,32050,32051,32052,32053,32054,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,32091,32092,32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,32106,32107,32108,32109,32110,32111,32112,32113,32114,32115,32116,32117,32118,32119,32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,32145,32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32166,32167,32168,32169,32170,32171,32172,32173,32174,32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,32187,32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,32200,32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,32214,32215,32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,32251,32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,32276,32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,32311,32312,32313,32314,32315,32316,32317,32318,32319,32320,32321,32322,32323,32324,32325,32326,32327,32328,32329,32330,32331,32332,32333,32334,32335,32336,32337,32338,32339,32340,32341,32342,32343,32344,32345,32346,32347,32348,32349,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,32383,32384,32385,32386,32387,32388,32389,32390,32391,32392,32393,32394,32395,32396,32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,32408,32409,32410,32411,32412,32413,32414,32415,32416,32417,32418,32419,32420,32421,32422,32423,32424,32425,32426,32427,32428,32429,32430,32431,32432,32433,32434,32435,32436,32437,32438,32439,32440,32441,32442,32443,32444,32445,32446,32447,32448,32449,32450,32451,32452,32453,32454,32455,32456,32457,32458,32459,32460,32461,32462,32463,32464,32465,32466,32467,32468,32469,32470,32471,32472,32473,32474,32475,32476,32477,32478,32479,32480,32481,32482,32483,32484,32485,32486,32487,32488,32489,32490,32491,32492,32493,32494,32495,32496,32497,32498,32499,32500,32501,32502,32503,32504,32505,32506,32507,32508,32509,32510,32511,32512,32513,32514,32515,32516,32517,32518,32519,32520,32521,32522,32523,32524,32525,32526,32527,32528,32529,32530,32531,32532,32533,32534,32535,32536,32537,32538,32539,32540,32541,32542,32543,32544,32545,32546,32547,32548,32549,32550,32551,32552,32553,32554,32555,32556,32557,32558,32559,32560,32561,32562,32563,32564,32565,32566,32567,32568,32569,32570,32571,32572,32573,32574,32575,32576,32577,32578,32579,32580,32581,32582,32583,32584,32585,32586,32587,32588,32589,32590,32591,32592,32593,32594,32595,32596,32597,32598,32599,32600,32601,32602,32603,32604,32605,32606,32607,32608,32609,32610,32611,32612,32613,32614,32615,32616,32617,32618,32619,32620,32621,32622,32623,32624,32625,32626,32627,32628,32629,32630,32631,32632,32633,32634,32635,32636,32637,32638,32639,32640,32641,32642,32643,32644,32645,32646,32647,32648,32649,32650,32651,32652,32653,32654,32655,32656,32657,32658,32659,32660,32661,32662,32663,32664,32665,32666,32667,32668,32669,32670,32671,32672,32673,32674,32675,32676,32677,32678,32679,32680,32681,32682,32683,32684,32685,32686,32687,32688,32689,32690,32691,32692,32693,32694,32695,32696,32697,32698,32699,32700,32701,32702,32703,32704,32705,32706,32707,32708,32709,32710,32711,32712,32713,32714,32715,32716,32717,32718,32719,32720,32721,32722,32723,32724,32725,32726,32727,32728,32729,32730,32731,32732,32733,32734,32735,32736,32737,32738,32739,32740,32741,32742,32743,32744,32745,32746,32747,32748,32749,32750,32751,32752,32753,32754,32755,32756,32757,32758,32759,32760,32761,32762,32763,32764,32765,32766,32767,32768,32769,32770,32771,32772,32773,32774,32775,32776,32777,32778,32779,32780,32781,32782,32783,32784,32785,32786,32787,32788,32789,32790,32791,32792,32793,32794,32795,32796,32797,32798,32799,32800,32801,32802,32803,32804,32805,32806,32807,32808,32809,32810,32811,32812,32813,32814,32815,32816,32817,32818,32819,32820,32821,32822,32823,32824,32825,32826,32827,32828,32829,32830,32831,32832,32833,32834,32835,32836,32837,32838,32839,32840,32841,32842,32843,32844,32845,32846,32847,32848,32849,32850,32851,32852,32853,32854,32855,32856,32857,32858,32859,32860,32861,32862,32863,32864,32865,32866,32867,32868,32869,32870,32871,32872,32873,32874,32875,32876,32877,32878,32879,32880,32881,32882,32883,32884,32885,32886,32887,32888,32889,32890,32891,32892,32893,32894,32895,32896,32897,32898,32899,32900,32901,32902,32903,32904,32905,32906,32907,32908,32909,32910,32911,32912,32913,32914,32915,32916,32917,32918,32919,32920,32921,32922,32923,32924,32925,32926,32927,32928,32929,32930,32931,32932,32933,32934,32935,32936,32937,32938,32939,32940,32941,32942,32943,32944,32945,32946,32947,32948,32949,32950,32951,32952,32953,32954,32955,32956,32957,32958,32959,32960,32961,32962,32963,32964,32965,32966,32967,32968,32969,32970,32971,32972,32973,32974,32975,32976,32977,32978,32979,32980,32981,32982,32983,32984,32985,32986,32987,32988,32989,32990,32991,32992,32993,32994,32995,32996,32997,32998,32999,33000,33001,33002,33003,33004,33005,33006,33007,33008,33009,33010,33011,33012,33013,33014,33015,33016,33017,33018,33019,33020,33021,33022,33023,33024,33025,33026,33027,33028,33029,33030,33031,33032,33033,33034,33035,33036,33037,33038,33039,33040,33041,33042,33043,33044,33045,33046,33047,33048,33049,33050,33051,33052,33053,33054,33055,33056,33057,33058,33059,33060,33061,33062,33063,33064,33065,33066,33067,33068,33069,33070,33071,33072,33073,33074,33075,33076,33077,33078,33079,33080,33081,33082,33083,33084,33085,33086,33087,33088,33089,33090,33091,33092,33093,33094,33095,33096,33097,33098,33099,33100,33101,33102,33103,33104,33105,33106,33107,33108,33109,33110,33111,33112,33113,33114,33115,33116,33117,33118,33119,33120,33121,33122,33123,33124,33125,33126,33127,33128,33129,33130,33131,33132,33133,33134,33135,33136,33137,33138,33139,33140,33141,33142,33143,33144,33145,33146,33147,33148,33149,33150,33151,33152,33153,33154,33155,33156,33157,33158,33159,33160,33161,33162,33163,33164,33165,33166,33167,33168,33169,33170,33171,33172,33173,33174,33175,33176,33177,33178,33179,33180,33181,33182,33183,33184,33185,33186,33187,33188,33189,33190,33191,33192,33193,33194,33195,33196,33197,33198,33199,33200,33201,33202,33203,33204,33205,33206,33207,33208,33209,33210,33211,33212,33213,33214,33215,33216,33217,33218,33219,33220,33221,33222,33223,33224,33225,33226,33227,33228,33229,33230,33231,33232,33233,33234,33235,33236,33237,33238,33239,33240,33241,33242,33243,33244,33245,33246,33247,33248,33249,33250,33251,33252,33253,33254,33255,33256,33257,33258,33259,33260,33261,33262,33263,33264,33265,33266,33267,33268,33269,33270,33271,33272,33273,33274,33275,33276,33277,33278,33279,33280,33281,33282,33283,33284,33285,33286,33287,33288,33289,33290,33291,33292,33293,33294,33295,33296,33297,33298,33299,33300,33301,33302,33303,33304,33305,33306,33307,33308,33309,33310,33311,33312,33313,33314,33315,33316,33317,33318,33319,33320,33321,33322,33323,33324,33325,33326,33327,33328,33329,33330,33331,33332,33333,33334,33335,33336,33337,33338,33339,33340,33341,33342,33343,33344,33345,33346,33347,33348,33349,33350,33351,33352,33353,33354,33355,33356,33357,33358,33359,33360,33361,33362,33363,33364,33365,33366,33367,33368,33369,33370,33371,33372,33373,33374,33375,33376,33377,33378,33379,33380,33381,33382,33383,33384,33385,33386,33387,33388,33389,33390,33391,33392,33393,33394,33395,33396,33397,33398,33399,33400,33401,33402,33403,33404,33405,33406,33407,33408,33409,33410,33411,33412,33413,33414,33415,33416,33417,33418,33419,33420,33421,33422,33423,33424,33425,33426,33427,33428,33429,33430,33431,33432,33433,33434,33435,33436,33437,33438,33439,33440,33441,33442,33443,33444,33445,33446,33447,33448,33449,33450,33451,33452,33453,33454,33455,33456,33457,33458,33459,33460,33461,33462,33463,33464,33465,33466,33467,33468,33469,33470,33471,33472,33473,33474,33475,33476,33477,33478,33479,33480,33481,33482,33483,33484,33485,33486,33487,33488,33489,33490,33491,33492,33493,33494,33495,33496,33497,33498,33499,33500,33501,33502,33503,33504,33505,33506,33507,33508,33509,33510,33511,33512,33513,33514,33515,33516,33517,33518,33519,33520,33521,33522,33523,33524,33525,33526,33527,33528,33529,33530,33531,33532,33533,33534,33535,33536,33537,33538,33539,33540,33541,33542,33543,33544,33545,33546,33547,33548,33549,33550,33551,33552,33553,33554,33555,33556,33557,33558,33559,33560,33561,33562,33563,33564,33565,33566,33567,33568,33569,33570,33571,33572,33573,33574,33575,33576,33577,33578,33579,33580,33581,33582,33583,33584,33585,33586,33587,33588,33589,33590,33591,33592,33593,33594,33595,33596,33597,33598,33599,33600,33601,33602,33603,33604,33605,33606,33607,33608,33609,33610,33611,33612,33613,33614,33615,33616,33617,33618,33619,33620,33621,33622,33623,33624,33625,33626,33627,33628,33629,33630,33631,33632,33633,33634,33635,33636,33637,33638,33639,33640,33641,33642,33643,33644,33645,33646,33647,33648,33649,33650,33651,33652,33653,33654,33655,33656,33657,33658,33659,33660,33661,33662,33663,33664,33665,33666,33667,33668,33669,33670,33671,33672,33673,33674,33675,33676,33677,33678,33679,33680,33681,33682,33683,33684,33685,33686,33687,33688,33689,33690,33691,33692,33693,33694,33695,33696,33697,33698,33699,33700,33701,33702,33703,33704,33705,33706,33707,33708,33709,33710,33711,33712,33713,33714,33715,33716,33717,33718,33719,33720,33721,33722,33723,33724,33725,33726,33727,33728,33729,33730,33731,33732,33733,33734,33735,33736,33737,33738,33739,33740,33741,33742,33743,33744,33745,33746,33747,33748,33749,33750,33751,33752,33753,33754,33755,33756,33757,33758,33759,33760,33761,33762,33763,33764,33765,33766,33767,33768,33769,33770,33771,33772,33773,33774,33775,33776,33777,33778,33779,33780,33781,33782,33783,33784,33785,33786,33787,33788,33789,33790,33791,33792,33793,33794,33795,33796,33797,33798,33799,33800,33801,33802,33803,33804,33805,33806,33807,33808,33809,33810,33811,33812,33813,33814,33815,33816,33817,33818,33819,33820,33821,33822,33823,33824,33825,33826,33827,33828,33829,33830,33831,33832,33833,33834,33835,33836,33837,33838,33839,33840,33841,33842,33843,33844,33845,33846,33847,33848,33849,33850,33851,33852,33853,33854,33855,33856,33857,33858,33859,33860,33861,33862,33863,33864,33865,33866,33867,33868,33869,33870,33871,33872,33873,33874,33875,33876,33877,33878,33879,33880,33881,33882,33883,33884,33885,33886,33887,33888,33889,33890,33891,33892,33893,33894,33895,33896,33897,33898,33899,33900,33901,33902,33903,33904,33905,33906,33907,33908,33909,33910,33911,33912,33913,33914,33915,33916,33917,33918,33919,33920,33921,33922,33923,33924,33925,33926,33927,33928,33929,33930,33931,33932,33933,33934,33935,33936,33937,33938,33939,33940,33941,33942,33943,33944,33945,33946,33947,33948,33949,33950,33951,33952,33953,33954,33955,33956,33957,33958,33959,33960,33961,33962,33963,33964,33965,33966,33967,33968,33969,33970,33971,33972,33973,33974,33975,33976,33977,33978,33979,33980,33981,33982,33983,33984,33985,33986,33987,33988,33989,33990,33991,33992,33993,33994,33995,33996,33997,33998,33999,34000,34001,34002,34003,34004,34005,34006,34007,34008,34009,34010,34011,34012,34013,34014,34015,34016,34017,34018,34019,34020,34021,34022,34023,34024,34025,34026,34027,34028,34029,34030,34031,34032,34033,34034,34035,34036,34037,34038,34039,34040,34041,34042,34043,34044,34045,34046,34047,34048,34049,34050,34051,34052,34053,34054,34055,34056,34057,34058,34059,34060,34061,34062,34063,34064,34065,34066,34067,34068,34069,34070,34071,34072,34073,34074,34075,34076,34077,34078,34079,34080,34081,34082,34083,34084,34085,34086,34087,34088,34089,34090,34091,34092,34093,34094,34095,34096,34097,34098,34099,34100,34101,34102,34103,34104,34105,34106,34107,34108,34109,34110,34111,34112,34113,34114,34115,34116,34117,34118,34119,34120,34121,34122,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,34134,34135,34136,34137,34138,34139,34140,34141,34142,34143,34144,34145,34146,34147,34148,34149,34150,34151,34152,34153,34154,34155,34156,34157,34158,34159,34160,34161,34162,34163,34164,34165,34166,34167,34168,34169,34170,34171,34172,34173,34174,34175,34176,34177,34178,34179,34180,34181,34182,34183,34184,34185,34186,34187,34188,34189,34190,34191,34192,34193,34194,34195,34196,34197,34198,34199,34200,34201,34202,34203,34204,34205,34206,34207,34208,34209,34210,34211,34212,34213,34214,34215,34216,34217,34218,34219,34220,34221,34222,34223,34224,34225,34226,34227,34228,34229,34230,34231,34232,34233,34234,34235,34236,34237,34238,34239,34240,34241,34242,34243,34244,34245,34246,34247,34248,34249,34250,34251,34252,34253,34254,34255,34256,34257,34258,34259,34260,34261,34262,34263,34264,34265,34266,34267,34268,34269,34270,34271,34272,34273,34274,34275,34276,34277,34278,34279,34280,34281,34282,34283,34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,34297,34298,34299,34300,34301,34302,34303,34304,34305,34306,34307,34308,34309,34310,34311,34312,34313,34314,34315,34316,34317,34318,34319,34320,34321,34322,34323,34324,34325,34326,34327,34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,34339,34340,34341,34342,34343,34344,34345,34346,34347,34348,34349,34350,34351,34352,34353,34354,34355,34356,34357,34358,34359,34360,34361,34362,34363,34364,34365,34366,34367,34368,34369,34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34381,34382,34383,34384,34385,34386,34387,34388,34389,34390,34391,34392,34393,34394,34395,34396,34397,34398,34399,34400,34401,34402,34403,34404,34405,34406,34407,34408,34409,34410,34411,34412,34413,34414,34415,34416,34417,34418,34419,34420,34421,34422,34423,34424,34425,34426,34427,34428,34429,34430,34431,34432,34433,34434,34435,34436,34437,34438,34439,34440,34441,34442,34443,34444,34445,34446,34447,34448,34449,34450,34451,34452,34453,34454,34455,34456,34457,34458,34459,34460,34461,34462,34463,34464,34465,34466,34467,34468,34469,34470,34471,34472,34473,34474,34475,34476,34477,34478,34479,34480,34481,34482,34483,34484,34485,34486,34487,34488,34489,34490,34491,34492,34493,34494,34495,34496,34497,34498,34499,34500,34501,34502,34503,34504,34505,34506,34507,34508,34509,34510,34511,34512,34513,34514,34515,34516,34517,34518,34519,34520,34521,34522,34523,34524,34525,34526,34527,34528,34529,34530,34531,34532,34533,34534,34535,34536,34537,34538,34539,34540,34541,34542,34543,34544,34545,34546,34547,34548,34549,34550,34551,34552,34553,34554,34555,34556,34557,34558,34559,34560,34561,34562,34563,34564,34565,34566,34567,34568,34569,34570,34571,34572,34573,34574,34575,34576,34577,34578,34579,34580,34581,34582,34583,34584,34585,34586,34587,34588,34589,34590,34591,34592,34593,34594,34595,34596,34597,34598,34599,34600,34601,34602,34603,34604,34605,34606,34607,34608,34609,34610,34611,34612,34613,34614,34615,34616,34617,34618,34619,34620,34621,34622,34623,34624,34625,34626,34627,34628,34629,34630,34631,34632,34633,34634,34635,34636,34637,34638,34639,34640,34641,34642,34643,34644,34645,34646,34647,34648,34649,34650,34651,34652,34653,34654,34655,34656,34657,34658,34659,34660,34661,34662,34663,34664,34665,34666,34667,34668,34669,34670,34671,34672,34673,34674,34675,34676,34677,34678,34679,34680,34681,34682,34683,34684,34685,34686,34687,34688,34689,34690,34691,34692,34693,34694,34695,34696,34697,34698,34699,34700,34701,34702,34703,34704,34705,34706,34707,34708,34709,34710,34711,34712,34713,34714,34715,34716,34717,34718,34719,34720,34721,34722,34723,34724,34725,34726,34727,34728,34729,34730,34731,34732,34733,34734,34735,34736,34737,34738,34739,34740,34741,34742,34743,34744,34745,34746,34747,34748,34749,34750,34751,34752,34753,34754,34755,34756,34757,34758,34759,34760,34761,34762,34763,34764,34765,34766,34767,34768,34769,34770,34771,34772,34773,34774,34775,34776,34777,34778,34779,34780,34781,34782,34783,34784,34785,34786,34787,34788,34789,34790,34791,34792,34793,34794,34795,34796,34797,34798,34799,34800,34801,34802,34803,34804,34805,34806,34807,34808,34809,34810,34811,34812,34813,34814,34815,34816,34817,34818,34819,34820,34821,34822,34823,34824,34825,34826,34827,34828,34829,34830,34831,34832,34833,34834,34835,34836,34837,34838,34839,34840,34841,34842,34843,34844,34845,34846,34847,34848,34849,34850,34851,34852,34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34866,34867,34868,34869,34870,34871,34872,34873,34874,34875,34876,34877,34878,34879,34880,34881,34882,34883,34884,34885,34886,34887,34888,34889,34890,34891,34892,34893,34894,34895,34896,34897,34898,34899,34900,34901,34902,34903,34904,34905,34906,34907,34908,34909,34910,34911,34912,34913,34914,34915,34916,34917,34918,34919,34920,34921,34922,34923,34924,34925,34926,34927,34928,34929,34930,34931,34932,34933,34934,34935,34936,34937,34938,34939,34940,34941,34942,34943,34944,34945,34946,34947,34948,34949,34950,34951,34952,34953,34954,34955,34956,34957,34958,34959,34960,34961,34962,34963,34964,34965,34966,34967,34968,34969,34970,34971,34972,34973,34974,34975,34976,34977,34978,34979,34980,34981,34982,34983,34984,34985,34986,34987,34988,34989,34990,34991,34992,34993,34994,34995,34996,34997,34998,34999,35000,35001,35002,35003,35004,35005,35006,35007,35008,35009,35010,35011,35012,35013,35014,35015,35016,35017,35018,35019,35020,35021,35022,35023,35024,35025,35026,35027,35028,35029,35030,35031,35032,35033,35034,35035,35036,35037,35038,35039,35040,35041,35042,35043,35044,35045,35046,35047,35048,35049,35050,35051,35052,35053,35054,35055,35056,35057,35058,35059,35060,35061,35062,35063,35064,35065,35066,35067,35068,35069,35070,35071,35072,35073,35074,35075,35076,35077,35078,35079,35080,35081,35082,35083,35084,35085,35086,35087,35088,35089,35090,35091,35092,35093,35094,35095,35096,35097,35098,35099,35100,35101,35102,35103,35104,35105,35106,35107,35108,35109,35110,35111,35112,35113,35114,35115,35116,35117,35118,35119,35120,35121,35122,35123,35124,35125,35126,35127,35128,35129,35130,35131,35132,35133,35134,35135,35136,35137,35138,35139,35140,35141,35142,35143,35144,35145,35146,35147,35148,35149,35150,35151,35152,35153,35154,35155,35156,35157,35158,35159,35160,35161,35162,35163,35164,35165,35166,35167,35168,35169,35170,35171,35172,35173,35174,35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,35185,35186,35187,35188,35189,35190,35191,35192,35193,35194,35195,35196,35197,35198,35199,35200,35201,35202,35203,35204,35205,35206,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217,35218,35219,35220,35221,35222,35223,35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,35234,35235,35236,35237,35238,35239,35240,35241,35242,35243,35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,35257,35258,35259,35260,35261,35262,35263,35264,35265,35266,35267,35268,35269,35270,35271,35272,35273,35274,35275,35276,35277,35278,35279,35280,35281,35282,35283,35284,35285,35286,35287,35288,35289,35290,35291,35292,35293,35294,35295,35296,35297,35298,35299,35300,35301,35302,35303,35304,35305,35306,35307,35308,35309,35310,35311,35312,35313,35314,35315,35316,35317,35318,35319,35320,35321,35322,35323,35324,35325,35326,35327,35328,35329,35330,35331,35332,35333,35334,35335,35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,35349,35350,35351,35352,35353,35354,35355,35356,35357,35358,35359,35360,35361,35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,35372,35373,35374,35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,35385,35386,35387,35388,35389,35390,35391,35392,35393,35394,35395,35396,35397,35398,35399,35400,35401,35402,35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,35413,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,35424,35425,35426,35427,35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,35449,35450,35451,35452,35453,35454,35455,35456,35457,35458,35459,35460,35461,35462,35463,35464,35465,35466,35467,35468,35469,35470,35471,35472,35473,35474,35475,35476,35477,35478,35479,35480,35481,35482,35483,35484,35485,35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496,35497,35498,35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509,35510,35511,35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522,35523,35524,35525,35526,35527,35528,35529,35530,35531,35532,35533,35534,35535,35536,35537,35538,35539,35540,35541,35542,35543,35544,35545,35546,35547,35548,35549,35550,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586,35587,35588,35589,35590,35591,35592,35593,35594,35595,35596,35597,35598,35599,35600,35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613,35614,35615,35616,35617,35618,35619,35620,35621,35622,35623,35624,35625,35626,35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639,35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652,35653,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,35664,35665,35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,35677,35678,35679,35680,35681,35682,35683,35684,35685,35686,35687,35688,35689,35690,35691,35692,35693,35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706,35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,35744,35745,35746,35747,35748,35749,35750,35751,35752,35753,35754,35755,35756,35757,35758,35759,35760,35761,35762,35763,35764,35765,35766,35767,35768,35769,35770,35771,35772,35773,35774,35775,35776,35777,35778,35779,35780,35781,35782,35783,35784,35785,35786,35787,35788,35789,35790,35791,35792,35793,35794,35795,35796,35797,35798,35799,35800,35801,35802,35803,35804,35805,35806,35807,35808,35809,35810,35811,35812,35813,35814,35815,35816,35817,35818,35819,35820,35821,35822,35823,35824,35825,35826,35827,35828,35829,35830,35831,35832,35833,35834,35835,35836,35837,35838,35839,35840,35841,35842,35843,35844,35845,35846,35847,35848,35849,35850,35851,35852,35853,35854,35855,35856,35857,35858,35859,35860,35861,35862,35863,35864,35865,35866,35867,35868,35869,35870,35871,35872,35873,35874,35875,35876,35877,35878,35879,35880,35881,35882,35883,35884,35885,35886,35887,35888,35889,35890,35891,35892,35893,35894,35895,35896,35897,35898,35899,35900,35901,35902,35903,35904,35905,35906,35907,35908,35909,35910,35911,35912,35913,35914,35915,35916,35917,35918,35919,35920,35921,35922,35923,35924,35925,35926,35927,35928,35929,35930,35931,35932,35933,35934,35935,35936,35937,35938,35939,35940,35941,35942,35943,35944,35945,35946,35947,35948,35949,35950,35951,35952,35953,35954,35955,35956,35957,35958,35959,35960,35961,35962,35963,35964,35965,35966,35967,35968,35969,35970,35971,35972,35973,35974,35975,35976,35977,35978,35979,35980,35981,35982,35983,35984,35985,35986,35987,35988,35989,35990,35991,35992,35993,35994,35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,36011,36012,36013,36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,36063,36064,36065,36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,36076,36077,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,36090,36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,36102,36103,36104,36105,36106,36107,36108,36109,36110,36111,36112,36113,36114,36115,36116,36117,36118,36119,36120,36121,36122,36123,36124,36125,36126,36127,36128,36129,36130,36131,36132,36133,36134,36135,36136,36137,36138,36139,36140,36141,36142,36143,36144,36145,36146,36147,36148,36149,36150,36151,36152,36153,36154,36155,36156,36157,36158,36159,36160,36161,36162,36163,36164,36165,36166,36167,36168,36169,36170,36171,36172,36173,36174,36175,36176,36177,36178,36179,36180,36181,36182,36183,36184,36185,36186,36187,36188,36189,36190,36191,36192,36193,36194,36195,36196,36197,36198,36199,36200,36201,36202,36203,36204,36205,36206,36207,36208,36209,36210,36211,36212,36213,36214,36215,36216,36217,36218,36219,36220,36221,36222,36223,36224,36225,36226,36227,36228,36229,36230,36231,36232,36233,36234,36235,36236,36237,36238,36239,36240,36241,36242,36243,36244,36245,36246,36247,36248,36249,36250,36251,36252,36253,36254,36255,36256,36257,36258,36259,36260,36261,36262,36263,36264,36265,36266,36267,36268,36269,36270,36271,36272,36273,36274,36275,36276,36277,36278,36279,36280,36281,36282,36283,36284,36285,36286,36287,36288,36289,36290,36291,36292,36293,36294,36295,36296,36297,36298,36299,36300,36301,36302,36303,36304,36305,36306,36307,36308,36309,36310,36311,36312,36313,36314,36315,36316,36317,36318,36319,36320,36321,36322,36323,36324,36325,36326,36327,36328,36329,36330,36331,36332,36333,36334,36335,36336,36337,36338,36339,36340,36341,36342,36343,36344,36345,36346,36347,36348,36349,36350,36351,36352,36353,36354,36355,36356,36357,36358,36359,36360,36361,36362,36363,36364,36365,36366,36367,36368,36369,36370,36371,36372,36373,36374,36375,36376,36377,36378,36379,36380,36381,36382,36383,36384,36385,36386,36387,36388,36389,36390,36391,36392,36393,36394,36395,36396,36397,36398,36399,36400,36401,36402,36403,36404,36405,36406,36407,36408,36409,36410,36411,36412,36413,36414,36415,36416,36417,36418,36419,36420,36421,36422,36423,36424,36425,36426,36427,36428,36429,36430,36431,36432,36433,36434,36435,36436,36437,36438,36439,36440,36441,36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,36454,36455,36456,36457,36458,36459,36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,36471,36472,36473,36474,36475,36476,36477,36478,36479,36480,36481,36482,36483,36484,36485,36486,36487,36488,36489,36490,36491,36492,36493,36494,36495,36496,36497,36498,36499,36500,36501,36502,36503,36504,36505,36506,36507,36508,36509,36510,36511,36512,36513,36514,36515,36516,36517,36518,36519,36520,36521,36522,36523,36524,36525,36526,36527,36528,36529,36530,36531,36532,36533,36534,36535,36536,36537,36538,36539,36540,36541,36542,36543,36544,36545,36546,36547,36548,36549,36550,36551,36552,36553,36554,36555,36556,36557,36558,36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569,36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,36580,36581,36582,36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,36595,36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,36608,36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,36621,36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,36634,36635,36636,36637,36638,36639,36640,36641,36642,36643,36644,36645,36646,36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659,36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672,36673,36674,36675,36676,36677,36678,36679,36680,36681,36682,36683,36684,36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,36698,36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,36709,36710,36711,36712,36713,36714,36715,36716,36717,36718,36719,36720,36721,36722,36723,36724,36725,36726,36727,36728,36729,36730,36731,36732,36733,36734,36735,36736,36737,36738,36739,36740,36741,36742,36743,36744,36745,36746,36747,36748,36749,36750,36751,36752,36753,36754,36755,36756,36757,36758,36759,36760,36761,36762,36763,36764,36765,36766,36767,36768,36769,36770,36771,36772,36773,36774,36775,36776,36777,36778,36779,36780,36781,36782,36783,36784,36785,36786,36787,36788,36789,36790,36791,36792,36793,36794,36795,36796,36797,36798,36799,36800,36801,36802,36803,36804,36805,36806,36807,36808,36809,36810,36811,36812,36813,36814,36815,36816,36817,36818,36819,36820,36821,36822,36823,36824,36825,36826,36827,36828,36829,36830,36831,36832,36833,36834,36835,36836,36837,36838,36839,36840,36841,36842,36843,36844,36845,36846,36847,36848,36849,36850,36851,36852,36853,36854,36855,36856,36857,36858,36859,36860,36861,36862,36863,36864,36865,36866,36867,36868,36869,36870,36871,36872,36873,36874,36875,36876,36877,36878,36879,36880,36881,36882,36883,36884,36885,36886,36887,36888,36889,36890,36891,36892,36893,36894,36895,36896,36897,36898,36899,36900,36901,36902,36903,36904,36905,36906,36907,36908,36909,36910,36911,36912,36913,36914,36915,36916,36917,36918,36919,36920,36921,36922,36923,36924,36925,36926,36927,36928,36929,36930,36931,36932,36933,36934,36935,36936,36937,36938,36939,36940,36941,36942,36943,36944,36945,36946,36947,36948,36949,36950,36951,36952,36953,36954,36955,36956,36957,36958,36959,36960,36961,36962,36963,36964,36965,36966,36967,36968,36969,36970,36971,36972,36973,36974,36975,36976,36977,36978,36979,36980,36981,36982,36983,36984,36985,36986,36987,36988,36989,36990,36991,36992,36993,36994,36995,36996,36997,36998,36999,37000,37001,37002,37003,37004,37005,37006,37007,37008,37009,37010,37011,37012,37013,37014,37015,37016,37017,37018,37019,37020,37021,37022,37023,37024,37025,37026,37027,37028,37029,37030,37031,37032,37033,37034,37035,37036,37037,37038,37039,37040,37041,37042,37043,37044,37045,37046,37047,37048,37049,37050,37051,37052,37053,37054,37055,37056,37057,37058,37059,37060,37061,37062,37063,37064,37065,37066,37067,37068,37069,37070,37071,37072,37073,37074,37075,37076,37077,37078,37079,37080,37081,37082,37083,37084,37085,37086,37087,37088,37089,37090,37091,37092,37093,37094,37095,37096,37097,37098,37099,37100,37101,37102,37103,37104,37105,37106,37107,37108,37109,37110,37111,37112,37113,37114,37115,37116,37117,37118,37119,37120,37121,37122,37123,37124,37125,37126,37127,37128,37129,37130,37131,37132,37133,37134,37135,37136,37137,37138,37139,37140,37141,37142,37143,37144,37145,37146,37147,37148,37149,37150,37151,37152,37153,37154,37155,37156,37157,37158,37159,37160,37161,37162,37163,37164,37165,37166,37167,37168,37169,37170,37171,37172,37173,37174,37175,37176,37177,37178,37179,37180,37181,37182,37183,37184,37185,37186,37187,37188,37189,37190,37191,37192,37193,37194,37195,37196,37197,37198,37199,37200,37201,37202,37203,37204,37205,37206,37207,37208,37209,37210,37211,37212,37213,37214,37215,37216,37217,37218,37219,37220,37221,37222,37223,37224,37225,37226,37227,37228,37229,37230,37231,37232,37233,37234,37235,37236,37237,37238,37239,37240,37241,37242,37243,37244,37245,37246,37247,37248,37249,37250,37251,37252,37253,37254,37255,37256,37257,37258,37259,37260,37261,37262,37263,37264,37265,37266,37267,37268,37269,37270,37271,37272,37273,37274,37275,37276,37277,37278,37279,37280,37281,37282,37283,37284,37285,37286,37287,37288,37289,37290,37291,37292,37293,37294,37295,37296,37297,37298,37299,37300,37301,37302,37303,37304,37305,37306,37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,37318,37319,37320,37321,37322,37323,37324,37325,37326,37327,37328,37329,37330,37331,37332,37333,37334,37335,37336,37337,37338,37339,37340,37341,37342,37343,37344,37345,37346,37347,37348,37349,37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,37361,37362,37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,37374,37375,37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37387,37388,37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,37400,37401,37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,37413,37414,37415,37416,37417,37418,37419,37420,37421,37422,37423,37424,37425,37426,37427,37428,37429,37430,37431,37432,37433,37434,37435,37436,37437,37438,37439,37440,37441,37442,37443,37444,37445,37446,37447,37448,37449,37450,37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,37490,37491,37492,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,37504,37505,37506,37507,37508,37509,37510,37511,37512,37513,37514,37515,37516,37517,37518,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529,37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,37544,37545,37546,37547,37548,37549,37550,37551,37552,37553,37554,37555,37556,37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,37568,37569,37570,37571,37572,37573,37574,37575,37576,37577,37578,37579,37580,37581,37582,37583,37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,37595,37596,37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,37608,37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,37621,37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,37634,37635,37636,37637,37638,37639,37640,37641,37642,37643,37644,37645,37646,37647,37648,37649,37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,37661,37662,37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,37674,37675,37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,37687,37688,37689,37690,37691,37692,37693,37694,37695,37696,37697,37698,37699,37700,37701,37702,37703,37704,37705,37706,37707,37708,37709,37710,37711,37712,37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,37723,37724,37725,37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,37736,37737,37738,37739,37740,37741,37742,37743,37744,37745,37746,37747,37748,37749,37750,37751,37752,37753,37754,37755,37756,37757,37758,37759,37760,37761,37762,37763,37764,37765,37766,37767,37768,37769,37770,37771,37772,37773,37774,37775,37776,37777,37778,37779,37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792,37793,37794,37795,37796,37797,37798,37799,37800,37801,37802,37803,37804,37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,37815,37816,37817,37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,37828,37829,37830,37831,37832,37833,37834,37835,37836,37837,37838,37839,37840,37841,37842,37843,37844,37845,37846,37847,37848,37849,37850,37851,37852,37853,37854,37855,37856,37857,37858,37859,37860,37861,37862,37863,37864,37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,37878,37879,37880,37881,37882,37883,37884,37885,37886,37887,37888,37889,37890,37891,37892,37893,37894,37895,37896,37897,37898,37899,37900,37901,37902,37903,37904,37905,37906,37907,37908,37909,37910,37911,37912,37913,37914,37915,37916,37917,37918,37919,37920,37921,37922,37923,37924,37925,37926,37927,37928,37929,37930,37931,37932,37933,37934,37935,37936,37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,37949,37950,37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,37976,37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,37989,37990,37991,37992,37993,37994,37995,37996,37997,37998,37999,38000,38001,38002,38003,38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,38015,38016,38017,38018,38019,38020,38021,38022,38023,38024,38025,38026,38027,38028,38029,38030,38031,38032,38033,38034,38035,38036,38037,38038,38039,38040,38041,38042,38043,38044,38045,38046,38047,38048,38049,38050,38051,38052,38053,38054,38055,38056,38057,38058,38059,38060,38061,38062,38063,38064,38065,38066,38067,38068,38069,38070,38071,38072,38073,38074,38075,38076,38077,38078,38079,38080,38081,38082,38083,38084,38085,38086,38087,38088,38089,38090,38091,38092,38093,38094,38095,38096,38097,38098,38099,38100,38101,38102,38103,38104,38105,38106,38107,38108,38109,38110,38111,38112,38113,38114,38115,38116,38117,38118,38119,38120,38121,38122,38123,38124,38125,38126,38127,38128,38129,38130,38131,38132,38133,38134,38135,38136,38137,38138,38139,38140,38141,38142,38143,38144,38145,38146,38147,38148,38149,38150,38151,38152,38153,38154,38155,38156,38157,38158,38159,38160,38161,38162,38163,38164,38165,38166,38167,38168,38169,38170,38171,38172,38173,38174,38175,38176,38177,38178,38179,38180,38181,38182,38183,38184,38185,38186,38187,38188,38189,38190,38191,38192,38193,38194,38195,38196,38197,38198,38199,38200,38201,38202,38203,38204,38205,38206,38207,38208,38209,38210,38211,38212,38213,38214,38215,38216,38217,38218,38219,38220,38221,38222,38223,38224,38225,38226,38227,38228,38229,38230,38231,38232,38233,38234,38235,38236,38237,38238,38239,38240,38241,38242,38243,38244,38245,38246,38247,38248,38249,38250,38251,38252,38253,38254,38255,38256,38257,38258,38259,38260,38261,38262,38263,38264,38265,38266,38267,38268,38269,38270,38271,38272,38273,38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285,38286,38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,38313,38314,38315,38316,38317,38318,38319,38320,38321,38322,38323,38324,38325,38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336,38337,38338,38339,38340,38341,38342,38343,38344,38345,38346,38347,38348,38349,38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,38362,38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,38376,38377,38378,38379,38380,38381,38382,38383,38384,38385,38386,38387,38388,38389,38390,38391,38392,38393,38394,38395,38396,38397,38398,38399,38400,38401,38402,38403,38404,38405,38406,38407,38408,38409,38410,38411,38412,38413,38414,38415,38416,38417,38418,38419,38420,38421,38422,38423,38424,38425,38426,38427,38428,38429,38430,38431,38432,38433,38434,38435,38436,38437,38438,38439,38440,38441,38442,38443,38444,38445,38446,38447,38448,38449,38450,38451,38452,38453,38454,38455,38456,38457,38458,38459,38460,38461,38462,38463,38464,38465,38466,38467,38468,38469,38470,38471,38472,38473,38474,38475,38476,38477,38478,38479,38480,38481,38482,38483,38484,38485,38486,38487,38488,38489,38490,38491,38492,38493,38494,38495,38496,38497,38498,38499,38500,38501,38502,38503,38504,38505,38506,38507,38508,38509,38510,38511,38512,38513,38514,38515,38516,38517,38518,38519,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,38532,38533,38534,38535,38536,38537,38538,38539,38540,38541,38542,38543,38544,38545,38546,38547,38548,38549,38550,38551,38552,38553,38554,38555,38556,38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38567,38568,38569,38570,38571,38572,38573,38574,38575,38576,38577,38578,38579,38580,38581,38582,38583,38584,38585,38586,38587,38588,38589,38590,38591,38592,38593,38594,38595,38596,38597,38598,38599,38600,38601,38602,38603,38604,38605,38606,38607,38608,38609,38610,38611,38612,38613,38614,38615,38616,38617,38618,38619,38620,38621,38622,38623,38624,38625,38626,38627,38628,38629,38630,38631,38632,38633,38634,38635,38636,38637,38638,38639,38640,38641,38642,38643,38644,38645,38646,38647,38648,38649,38650,38651,38652,38653,38654,38655,38656,38657,38658,38659,38660,38661,38662,38663,38664,38665,38666,38667,38668,38669,38670,38671,38672,38673,38674,38675,38676,38677,38678,38679,38680,38681,38682,38683,38684,38685,38686,38687,38688,38689,38690,38691,38692,38693,38694,38695,38696,38697,38698,38699,38700,38701,38702,38703,38704,38705,38706,38707,38708,38709,38710,38711,38712,38713,38714,38715,38716,38717,38718,38719,38720,38721,38722,38723,38724,38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737,38738,38739,38740,38741,38742,38743,38744,38745,38746,38747,38748,38749,38750,38751,38752,38753,38754,38755,38756,38757,38758,38759,38760,38761,38762,38763,38764,38765,38766,38767,38768,38769,38770,38771,38772,38773,38774,38775,38776,38777,38778,38779,38780,38781,38782,38783,38784,38785,38786,38787,38788,38789,38790,38791,38792,38793,38794,38795,38796,38797,38798,38799,38800,38801,38802,38803,38804,38805,38806,38807,38808,38809,38810,38811,38812,38813,38814,38815,38816,38817,38818,38819,38820,38821,38822,38823,38824,38825,38826,38827,38828,38829,38830,38831,38832,38833,38834,38835,38836,38837,38838,38839,38840,38841,38842,38843,38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,38883,38884,38885,38886,38887,38888,38889,38890,38891,38892,38893,38894,38895,38896,38897,38898,38899,38900,38901,38902,38903,38904,38905,38906,38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,38918,38919,38920,38921,38922,38923,38924,38925,38926,38927,38928,38929,38930,38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,38943,38944,38945,38946,38947,38948,38949,38950,38951,38952,38953,38954,38955,38956,38957,38958,38959,38960,38961,38962,38963,38964,38965,38966,38967,38968,38969,38970,38971,38972,38973,38974,38975,38976,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986,38987,38988,38989,38990,38991,38992,38993,38994,38995,38996,38997,38998,38999,39000,39001,39002,39003,39004,39005,39006,39007,39008,39009,39010,39011,39012,39013,39014,39015,39016,39017,39018,39019,39020,39021,39022,39023,39024,39025,39026,39027,39028,39029,39030,39031,39032,39033,39034,39035,39036,39037,39038,39039,39040,39041,39042,39043,39044,39045,39046,39047,39048,39049,39050,39051,39052,39053,39054,39055,39056,39057,39058,39059,39060,39061,39062,39063,39064,39065,39066,39067,39068,39069,39070,39071,39072,39073,39074,39075,39076,39077,39078,39079,39080,39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,39092,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104,39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117,39118,39119,39120,39121,39122,39123,39124,39125,39126,39127,39128,39129,39130,39131,39132,39133,39134,39135,39136,39137,39138,39139,39140,39141,39142,39143,39144,39145,39146,39147,39148,39149,39150,39151,39152,39153,39154,39155,39156,39157,39158,39159,39160,39161,39162,39163,39164,39165,39166,39167,39168,39169,39170,39171,39172,39173,39174,39175,39176,39177,39178,39179,39180,39181,39182,39183,39184,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,39209,39210,39211,39212,39213,39214,39215,39216,39217,39218,39219,39220,39221,39222,39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,39236,39237,39238,39239,39240,39241,39242,39243,39244,39245,39246,39247,39248,39249,39250,39251,39252,39253,39254,39255,39256,39257,39258,39259,39260,39261,39262,39263,39264,39265,39266,39267,39268,39269,39270,39271,39272,39273,39274,39275,39276,39277,39278,39279,39280,39281,39282,39283,39284,39285,39286,39287,39288,39289,39290,39291,39292,39293,39294,39295,39296,39297,39298,39299,39300,39301,39302,39303,39304,39305,39306,39307,39308,39309,39310,39311,39312,39313,39314,39315,39316,39317,39318,39319,39320,39321,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331,39332,39333,39334,39335,39336,39337,39338,39339,39340,39341,39342,39343,39344,39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,39410,39411,39412,39413,39414,39415,39416,39417,39418,39419,39420,39421,39422,39423,39424,39425,39426,39427,39428,39429,39430,39431,39432,39433,39434,39435,39436,39437,39438,39439,39440,39441,39442,39443,39444,39445,39446,39447,39448,39449,39450,39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,39463,39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,39476,39477,39478,39479,39480,39481,39482,39483,39484,39485,39486,39487,39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,39526,39527,39528,39529,39530,39531,39532,39533,39534,39535,39536,39537,39538,39539,39540,39541,39542,39543,39544,39545,39546,39547,39548,39549,39550,39551,39552,39553,39554,39555,39556,39557,39558,39559,39560,39561,39562,39563,39564,39565,39566,39567,39568,39569,39570,39571,39572,39573,39574,39575,39576,39577,39578,39579,39580,39581,39582,39583,39584,39585,39586,39587,39588,39589,39590,39591,39592,39593,39594,39595,39596,39597,39598,39599,39600,39601,39602,39603,39604,39605,39606,39607,39608,39609,39610,39611,39612,39613,39614,39615,39616,39617,39618,39619,39620,39621,39622,39623,39624,39625,39626,39627,39628,39629,39630,39631,39632,39633,39634,39635,39636,39637,39638,39639,39640,39641,39642,39643,39644,39645,39646,39647,39648,39649,39650,39651,39652,39653,39654,39655,39656,39657,39658,39659,39660,39661,39662,39663,39664,39665,39666,39667,39668,39669,39670,39671,39672,39673,39674,39675,39676,39677,39678,39679,39680,39681,39682,39683,39684,39685,39686,39687,39688,39689,39690,39691,39692,39693,39694,39695,39696,39697,39698,39699,39700,39701,39702,39703,39704,39705,39706,39707,39708,39709,39710,39711,39712,39713,39714,39715,39716,39717,39718,39719,39720,39721,39722,39723,39724,39725,39726,39727,39728,39729,39730,39731,39732,39733,39734,39735,39736,39737,39738,39739,39740,39741,39742,39743,39744,39745,39746,39747,39748,39749,39750,39751,39752,39753,39754,39755,39756,39757,39758,39759,39760,39761,39762,39763,39764,39765,39766,39767,39768,39769,39770,39771,39772,39773,39774,39775,39776,39777,39778,39779,39780,39781,39782,39783,39784,39785,39786,39787,39788,39789,39790,39791,39792,39793,39794,39795,39796,39797,39798,39799,39800,39801,39802,39803,39804,39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,39934,39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946,39947,39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959,39960,39961,39962,39963,39964,39965,39966,39967,39968,39969,39970,39971,39972,39973,39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984,39985,39986,39987,39988,39989,39990,39991,39992,39993,39994,39995,39996,39997,39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,40010,40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,40023,40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,40036,40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,40049,40050,40051,40052,40053,40054,40055,40056,40057,40058,40059,40060,40061,40062,40063,40064,40065,40066,40067,40068,40069,40070,40071,40072,40073,40074,40075,40076,40077,40078,40079,40080,40081,40082,40083,40084,40085,40086,40087,40088,40089,40090,40091,40092,40093,40094,40095,40096,40097,40098,40099,40100,40101,40102,40103,40104,40105,40106,40107,40108,40109,40110,40111,40112,40113,40114,40115,40116,40117,40118,40119,40120,40121,40122,40123,40124,40125,40126,40127,40128,40129,40130,40131,40132,40133,40134,40135,40136,40137,40138,40139,40140,40141,40142,40143,40144,40145,40146,40147,40148,40149,40150,40151,40152,40153,40154,40155,40156,40157,40158,40159,40160,40161,40162,40163,40164,40165,40166,40167,40168,40169,40170,40171,40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,40184,40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,40197,40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,40210,40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,40223,40224,40225,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,40259,40260,40261,40262,40263,40264,40265,40266,40267,40268,40269,40270,40271,40272,40273,40274,40275,40276,40277,40278,40279,40280,40281,40282,40283,40284,40285,40286,40287,40288,40289,40290,40291,40292,40293,40294,40295,40296,40297,40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,40311,40312,40313,40314,40315,40316,40317,40318,40319,40320,40321,40322,40323,40324,40325,40326,40327,40328,40329,40330,40331,40332,40333,40334,40335,40336,40337,40338,40339,40340,40341,40342,40343,40344,40345,40346,40347,40348,40349,40350,40351,40352,40353,40354,40355,40356,40357,40358,40359,40360,40361,40362,40363,40364,40365,40366,40367,40368,40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,40380,40381,40382,40383,40384,40385,40386,40387,40388,40389,40390,40391,40392,40393,40394,40395,40396,40397,40398,40399,40400,40401,40402,40403,40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,40417,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,40429,40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,40442,40443,40444,40445,40446,40447,40448,40449,40450,40451,40452,40453,40454,40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,40466,40467,40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,40479,40480,40481,40482,40483,40484,40485,40486,40487,40488,40489,40490,40491,40492,40493,40494,40495,40496,40497,40498,40499,40500,40501,40502,40503,40504,40505,40506,40507,40508,40509,40510,40511,40512,40513,40514,40515,40516,40517,40518,40519,40520,40521,40522,40523,40524,40525,40526,40527,40528,40529,40530,40531,40532,40533,40534,40535,40536,40537,40538,40539,40540,40541,40542,40543,40544,40545,40546,40547,40548,40549,40550,40551,40552,40553,40554,40555,40556,40557,40558,40559,40560,40561,40562,40563,40564,40565,40566,40567,40568,40569,40570,40571,40572,40573,40574,40575,40576,40577,40578,40579,40580,40581,40582,40583,40584,40585,40586,40587,40588,40589,40590,40591,40592,40593,40594,40595,40596,40597,40598,40599,40600,40601,40602,40603,40604,40605,40606,40607,40608,40609,40610,40611,40612,40613,40614,40615,40616,40617,40618,40619,40620,40621,40622,40623,40624,40625,40626,40627,40628,40629,40630,40631,40632,40633,40634,40635,40636,40637,40638,40639,40640,40641,40642,40643,40644,40645,40646,40647,40648,40649,40650,40651,40652,40653,40654,40655,40656,40657,40658,40659,40660,40661,40662,40663,40664,40665,40666,40667,40668,40669,40670,40671,40672,40673,40674,40675,40676,40677,40678,40679,40680,40681,40682,40683,40684,40685,40686,40687,40688,40689,40690,40691,40692,40693,40694,40695,40696,40697,40698,40699,40700,40701,40702,40703,40704,40705,40706,40707,40708,40709,40710,40711,40712,40713,40714,40715,40716,40717,40718,40719,40720,40721,40722,40723,40724,40725,40726,40727,40728,40729,40730,40731,40732,40733,40734,40735,40736,40737,40738,40739,40740,40741,40742,40743,40744,40745,40746,40747,40748,40749,40750,40751,40752,40753,40754,40755,40756,40757,40758,40759,40760,40761,40762,40763,40764,40765,40766,40767,40768,40769,40770,40771,40772,40773,40774,40775,40776,40777,40778,40779,40780,40781,40782,40783,40784,40785,40786,40787,40788,40789,40790,40791,40792,40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805,40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830,40831,40832,40833,40834,40835,40836,40837,40838,40839,40840,40841,40842,40843,40844,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,40856,40857,40858,40859,40860,40861,40862,40863,40864,40865,40866,40867,40868,40869,40870,40871,40872,40873,40874,40875,40876,40877,40878,40879,40880,40881,40882,40883,40884,40885,40886,40887,40888,40889,40890,40891,40892,40893,40894,40895,40896,40897,40898,40899,40900,40901,40902,40903,40904,40905,40906,40907,40908,40909,40910,40911,40912,40913,40914,40915,40916,40917,40918,40919,40920,40921,40922,40923,40924,40925,40926,40927,40928,40929,40930,40931,40932,40933,40934,40935,40936,40937,40938,40939,40940,40941,40942,40943,40960,40961,40962,40963,40964,40965,40966,40967,40968,40969,40970,40971,40972,40973,40974,40975,40976,40977,40978,40979,40980,40981,40982,40983,40984,40985,40986,40987,40988,40989,40990,40991,40992,40993,40994,40995,40996,40997,40998,40999,41000,41001,41002,41003,41004,41005,41006,41007,41008,41009,41010,41011,41012,41013,41014,41015,41016,41017,41018,41019,41020,41021,41022,41023,41024,41025,41026,41027,41028,41029,41030,41031,41032,41033,41034,41035,41036,41037,41038,41039,41040,41041,41042,41043,41044,41045,41046,41047,41048,41049,41050,41051,41052,41053,41054,41055,41056,41057,41058,41059,41060,41061,41062,41063,41064,41065,41066,41067,41068,41069,41070,41071,41072,41073,41074,41075,41076,41077,41078,41079,41080,41081,41082,41083,41084,41085,41086,41087,41088,41089,41090,41091,41092,41093,41094,41095,41096,41097,41098,41099,41100,41101,41102,41103,41104,41105,41106,41107,41108,41109,41110,41111,41112,41113,41114,41115,41116,41117,41118,41119,41120,41121,41122,41123,41124,41125,41126,41127,41128,41129,41130,41131,41132,41133,41134,41135,41136,41137,41138,41139,41140,41141,41142,41143,41144,41145,41146,41147,41148,41149,41150,41151,41152,41153,41154,41155,41156,41157,41158,41159,41160,41161,41162,41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,41174,41175,41176,41177,41178,41179,41180,41181,41182,41183,41184,41185,41186,41187,41188,41189,41190,41191,41192,41193,41194,41195,41196,41197,41198,41199,41200,41201,41202,41203,41204,41205,41206,41207,41208,41209,41210,41211,41212,41213,41214,41215,41216,41217,41218,41219,41220,41221,41222,41223,41224,41225,41226,41227,41228,41229,41230,41231,41232,41233,41234,41235,41236,41237,41238,41239,41240,41241,41242,41243,41244,41245,41246,41247,41248,41249,41250,41251,41252,41253,41254,41255,41256,41257,41258,41259,41260,41261,41262,41263,41264,41265,41266,41267,41268,41269,41270,41271,41272,41273,41274,41275,41276,41277,41278,41279,41280,41281,41282,41283,41284,41285,41286,41287,41288,41289,41290,41291,41292,41293,41294,41295,41296,41297,41298,41299,41300,41301,41302,41303,41304,41305,41306,41307,41308,41309,41310,41311,41312,41313,41314,41315,41316,41317,41318,41319,41320,41321,41322,41323,41324,41325,41326,41327,41328,41329,41330,41331,41332,41333,41334,41335,41336,41337,41338,41339,41340,41341,41342,41343,41344,41345,41346,41347,41348,41349,41350,41351,41352,41353,41354,41355,41356,41357,41358,41359,41360,41361,41362,41363,41364,41365,41366,41367,41368,41369,41370,41371,41372,41373,41374,41375,41376,41377,41378,41379,41380,41381,41382,41383,41384,41385,41386,41387,41388,41389,41390,41391,41392,41393,41394,41395,41396,41397,41398,41399,41400,41401,41402,41403,41404,41405,41406,41407,41408,41409,41410,41411,41412,41413,41414,41415,41416,41417,41418,41419,41420,41421,41422,41423,41424,41425,41426,41427,41428,41429,41430,41431,41432,41433,41434,41435,41436,41437,41438,41439,41440,41441,41442,41443,41444,41445,41446,41447,41448,41449,41450,41451,41452,41453,41454,41455,41456,41457,41458,41459,41460,41461,41462,41463,41464,41465,41466,41467,41468,41469,41470,41471,41472,41473,41474,41475,41476,41477,41478,41479,41480,41481,41482,41483,41484,41485,41486,41487,41488,41489,41490,41491,41492,41493,41494,41495,41496,41497,41498,41499,41500,41501,41502,41503,41504,41505,41506,41507,41508,41509,41510,41511,41512,41513,41514,41515,41516,41517,41518,41519,41520,41521,41522,41523,41524,41525,41526,41527,41528,41529,41530,41531,41532,41533,41534,41535,41536,41537,41538,41539,41540,41541,41542,41543,41544,41545,41546,41547,41548,41549,41550,41551,41552,41553,41554,41555,41556,41557,41558,41559,41560,41561,41562,41563,41564,41565,41566,41567,41568,41569,41570,41571,41572,41573,41574,41575,41576,41577,41578,41579,41580,41581,41582,41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,41594,41595,41596,41597,41598,41599,41600,41601,41602,41603,41604,41605,41606,41607,41608,41609,41610,41611,41612,41613,41614,41615,41616,41617,41618,41619,41620,41621,41622,41623,41624,41625,41626,41627,41628,41629,41630,41631,41632,41633,41634,41635,41636,41637,41638,41639,41640,41641,41642,41643,41644,41645,41646,41647,41648,41649,41650,41651,41652,41653,41654,41655,41656,41657,41658,41659,41660,41661,41662,41663,41664,41665,41666,41667,41668,41669,41670,41671,41672,41673,41674,41675,41676,41677,41678,41679,41680,41681,41682,41683,41684,41685,41686,41687,41688,41689,41690,41691,41692,41693,41694,41695,41696,41697,41698,41699,41700,41701,41702,41703,41704,41705,41706,41707,41708,41709,41710,41711,41712,41713,41714,41715,41716,41717,41718,41719,41720,41721,41722,41723,41724,41725,41726,41727,41728,41729,41730,41731,41732,41733,41734,41735,41736,41737,41738,41739,41740,41741,41742,41743,41744,41745,41746,41747,41748,41749,41750,41751,41752,41753,41754,41755,41756,41757,41758,41759,41760,41761,41762,41763,41764,41765,41766,41767,41768,41769,41770,41771,41772,41773,41774,41775,41776,41777,41778,41779,41780,41781,41782,41783,41784,41785,41786,41787,41788,41789,41790,41791,41792,41793,41794,41795,41796,41797,41798,41799,41800,41801,41802,41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,41813,41814,41815,41816,41817,41818,41819,41820,41821,41822,41823,41824,41825,41826,41827,41828,41829,41830,41831,41832,41833,41834,41835,41836,41837,41838,41839,41840,41841,41842,41843,41844,41845,41846,41847,41848,41849,41850,41851,41852,41853,41854,41855,41856,41857,41858,41859,41860,41861,41862,41863,41864,41865,41866,41867,41868,41869,41870,41871,41872,41873,41874,41875,41876,41877,41878,41879,41880,41881,41882,41883,41884,41885,41886,41887,41888,41889,41890,41891,41892,41893,41894,41895,41896,41897,41898,41899,41900,41901,41902,41903,41904,41905,41906,41907,41908,41909,41910,41911,41912,41913,41914,41915,41916,41917,41918,41919,41920,41921,41922,41923,41924,41925,41926,41927,41928,41929,41930,41931,41932,41933,41934,41935,41936,41937,41938,41939,41940,41941,41942,41943,41944,41945,41946,41947,41948,41949,41950,41951,41952,41953,41954,41955,41956,41957,41958,41959,41960,41961,41962,41963,41964,41965,41966,41967,41968,41969,41970,41971,41972,41973,41974,41975,41976,41977,41978,41979,41980,41981,41982,41983,41984,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,41997,41998,41999,42000,42001,42002,42003,42004,42005,42006,42007,42008,42009,42010,42011,42012,42013,42014,42015,42016,42017,42018,42019,42020,42021,42022,42023,42024,42025,42026,42027,42028,42029,42030,42031,42032,42033,42034,42035,42036,42037,42038,42039,42040,42041,42042,42043,42044,42045,42046,42047,42048,42049,42050,42051,42052,42053,42054,42055,42056,42057,42058,42059,42060,42061,42062,42063,42064,42065,42066,42067,42068,42069,42070,42071,42072,42073,42074,42075,42076,42077,42078,42079,42080,42081,42082,42083,42084,42085,42086,42087,42088,42089,42090,42091,42092,42093,42094,42095,42096,42097,42098,42099,42100,42101,42102,42103,42104,42105,42106,42107,42108,42109,42110,42111,42112,42113,42114,42115,42116,42117,42118,42119,42120,42121,42122,42123,42124,42192,42193,42194,42195,42196,42197,42198,42199,42200,42201,42202,42203,42204,42205,42206,42207,42208,42209,42210,42211,42212,42213,42214,42215,42216,42217,42218,42219,42220,42221,42222,42223,42224,42225,42226,42227,42228,42229,42230,42231,42232,42233,42234,42235,42236,42237,42240,42241,42242,42243,42244,42245,42246,42247,42248,42249,42250,42251,42252,42253,42254,42255,42256,42257,42258,42259,42260,42261,42262,42263,42264,42265,42266,42267,42268,42269,42270,42271,42272,42273,42274,42275,42276,42277,42278,42279,42280,42281,42282,42283,42284,42285,42286,42287,42288,42289,42290,42291,42292,42293,42294,42295,42296,42297,42298,42299,42300,42301,42302,42303,42304,42305,42306,42307,42308,42309,42310,42311,42312,42313,42314,42315,42316,42317,42318,42319,42320,42321,42322,42323,42324,42325,42326,42327,42328,42329,42330,42331,42332,42333,42334,42335,42336,42337,42338,42339,42340,42341,42342,42343,42344,42345,42346,42347,42348,42349,42350,42351,42352,42353,42354,42355,42356,42357,42358,42359,42360,42361,42362,42363,42364,42365,42366,42367,42368,42369,42370,42371,42372,42373,42374,42375,42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,42386,42387,42388,42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,42399,42400,42401,42402,42403,42404,42405,42406,42407,42408,42409,42410,42411,42412,42413,42414,42415,42416,42417,42418,42419,42420,42421,42422,42423,42424,42425,42426,42427,42428,42429,42430,42431,42432,42433,42434,42435,42436,42437,42438,42439,42440,42441,42442,42443,42444,42445,42446,42447,42448,42449,42450,42451,42452,42453,42454,42455,42456,42457,42458,42459,42460,42461,42462,42463,42464,42465,42466,42467,42468,42469,42470,42471,42472,42473,42474,42475,42476,42477,42478,42479,42480,42481,42482,42483,42484,42485,42486,42487,42488,42489,42490,42491,42492,42493,42494,42495,42496,42497,42498,42499,42500,42501,42502,42503,42504,42505,42506,42507,42508,42512,42513,42514,42515,42516,42517,42518,42519,42520,42521,42522,42523,42524,42525,42526,42527,42538,42539,42560,42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,42572,42573,42574,42575,42576,42577,42578,42579,42580,42581,42582,42583,42584,42585,42586,42587,42588,42589,42590,42591,42592,42593,42594,42595,42596,42597,42598,42599,42600,42601,42602,42603,42604,42605,42606,42623,42624,42625,42626,42627,42628,42629,42630,42631,42632,42633,42634,42635,42636,42637,42638,42639,42640,42641,42642,42643,42644,42645,42646,42647,42648,42649,42650,42651,42652,42653,42656,42657,42658,42659,42660,42661,42662,42663,42664,42665,42666,42667,42668,42669,42670,42671,42672,42673,42674,42675,42676,42677,42678,42679,42680,42681,42682,42683,42684,42685,42686,42687,42688,42689,42690,42691,42692,42693,42694,42695,42696,42697,42698,42699,42700,42701,42702,42703,42704,42705,42706,42707,42708,42709,42710,42711,42712,42713,42714,42715,42716,42717,42718,42719,42720,42721,42722,42723,42724,42725,42726,42727,42728,42729,42730,42731,42732,42733,42734,42735,42775,42776,42777,42778,42779,42780,42781,42782,42783,42786,42787,42788,42789,42790,42791,42792,42793,42794,42795,42796,42797,42798,42799,42800,42801,42802,42803,42804,42805,42806,42807,42808,42809,42810,42811,42812,42813,42814,42815,42816,42817,42818,42819,42820,42821,42822,42823,42824,42825,42826,42827,42828,42829,42830,42831,42832,42833,42834,42835,42836,42837,42838,42839,42840,42841,42842,42843,42844,42845,42846,42847,42848,42849,42850,42851,42852,42853,42854,42855,42856,42857,42858,42859,42860,42861,42862,42863,42864,42865,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,42877,42878,42879,42880,42881,42882,42883,42884,42885,42886,42887,42888,42891,42892,42893,42894,42895,42896,42897,42898,42899,42900,42901,42902,42903,42904,42905,42906,42907,42908,42909,42910,42911,42912,42913,42914,42915,42916,42917,42918,42919,42920,42921,42922,42923,42924,42925,42926,42927,42928,42929,42930,42931,42932,42933,42934,42935,42936,42937,42999,43000,43001,43002,43003,43004,43005,43006,43007,43008,43009,43011,43012,43013,43015,43016,43017,43018,43020,43021,43022,43023,43024,43025,43026,43027,43028,43029,43030,43031,43032,43033,43034,43035,43036,43037,43038,43039,43040,43041,43042,43072,43073,43074,43075,43076,43077,43078,43079,43080,43081,43082,43083,43084,43085,43086,43087,43088,43089,43090,43091,43092,43093,43094,43095,43096,43097,43098,43099,43100,43101,43102,43103,43104,43105,43106,43107,43108,43109,43110,43111,43112,43113,43114,43115,43116,43117,43118,43119,43120,43121,43122,43123,43138,43139,43140,43141,43142,43143,43144,43145,43146,43147,43148,43149,43150,43151,43152,43153,43154,43155,43156,43157,43158,43159,43160,43161,43162,43163,43164,43165,43166,43167,43168,43169,43170,43171,43172,43173,43174,43175,43176,43177,43178,43179,43180,43181,43182,43183,43184,43185,43186,43187,43250,43251,43252,43253,43254,43255,43259,43261,43262,43274,43275,43276,43277,43278,43279,43280,43281,43282,43283,43284,43285,43286,43287,43288,43289,43290,43291,43292,43293,43294,43295,43296,43297,43298,43299,43300,43301,43312,43313,43314,43315,43316,43317,43318,43319,43320,43321,43322,43323,43324,43325,43326,43327,43328,43329,43330,43331,43332,43333,43334,43360,43361,43362,43363,43364,43365,43366,43367,43368,43369,43370,43371,43372,43373,43374,43375,43376,43377,43378,43379,43380,43381,43382,43383,43384,43385,43386,43387,43388,43396,43397,43398,43399,43400,43401,43402,43403,43404,43405,43406,43407,43408,43409,43410,43411,43412,43413,43414,43415,43416,43417,43418,43419,43420,43421,43422,43423,43424,43425,43426,43427,43428,43429,43430,43431,43432,43433,43434,43435,43436,43437,43438,43439,43440,43441,43442,43471,43488,43489,43490,43491,43492,43494,43495,43496,43497,43498,43499,43500,43501,43502,43503,43514,43515,43516,43517,43518,43520,43521,43522,43523,43524,43525,43526,43527,43528,43529,43530,43531,43532,43533,43534,43535,43536,43537,43538,43539,43540,43541,43542,43543,43544,43545,43546,43547,43548,43549,43550,43551,43552,43553,43554,43555,43556,43557,43558,43559,43560,43584,43585,43586,43588,43589,43590,43591,43592,43593,43594,43595,43616,43617,43618,43619,43620,43621,43622,43623,43624,43625,43626,43627,43628,43629,43630,43631,43632,43633,43634,43635,43636,43637,43638,43642,43646,43647,43648,43649,43650,43651,43652,43653,43654,43655,43656,43657,43658,43659,43660,43661,43662,43663,43664,43665,43666,43667,43668,43669,43670,43671,43672,43673,43674,43675,43676,43677,43678,43679,43680,43681,43682,43683,43684,43685,43686,43687,43688,43689,43690,43691,43692,43693,43694,43695,43697,43701,43702,43705,43706,43707,43708,43709,43712,43714,43739,43740,43741,43744,43745,43746,43747,43748,43749,43750,43751,43752,43753,43754,43762,43763,43764,43777,43778,43779,43780,43781,43782,43785,43786,43787,43788,43789,43790,43793,43794,43795,43796,43797,43798,43808,43809,43810,43811,43812,43813,43814,43816,43817,43818,43819,43820,43821,43822,43824,43825,43826,43827,43828,43829,43830,43831,43832,43833,43834,43835,43836,43837,43838,43839,43840,43841,43842,43843,43844,43845,43846,43847,43848,43849,43850,43851,43852,43853,43854,43855,43856,43857,43858,43859,43860,43861,43862,43863,43864,43865,43866,43868,43869,43870,43871,43872,43873,43874,43875,43876,43877,43888,43889,43890,43891,43892,43893,43894,43895,43896,43897,43898,43899,43900,43901,43902,43903,43904,43905,43906,43907,43908,43909,43910,43911,43912,43913,43914,43915,43916,43917,43918,43919,43920,43921,43922,43923,43924,43925,43926,43927,43928,43929,43930,43931,43932,43933,43934,43935,43936,43937,43938,43939,43940,43941,43942,43943,43944,43945,43946,43947,43948,43949,43950,43951,43952,43953,43954,43955,43956,43957,43958,43959,43960,43961,43962,43963,43964,43965,43966,43967,43968,43969,43970,43971,43972,43973,43974,43975,43976,43977,43978,43979,43980,43981,43982,43983,43984,43985,43986,43987,43988,43989,43990,43991,43992,43993,43994,43995,43996,43997,43998,43999,44000,44001,44002,44032,44033,44034,44035,44036,44037,44038,44039,44040,44041,44042,44043,44044,44045,44046,44047,44048,44049,44050,44051,44052,44053,44054,44055,44056,44057,44058,44059,44060,44061,44062,44063,44064,44065,44066,44067,44068,44069,44070,44071,44072,44073,44074,44075,44076,44077,44078,44079,44080,44081,44082,44083,44084,44085,44086,44087,44088,44089,44090,44091,44092,44093,44094,44095,44096,44097,44098,44099,44100,44101,44102,44103,44104,44105,44106,44107,44108,44109,44110,44111,44112,44113,44114,44115,44116,44117,44118,44119,44120,44121,44122,44123,44124,44125,44126,44127,44128,44129,44130,44131,44132,44133,44134,44135,44136,44137,44138,44139,44140,44141,44142,44143,44144,44145,44146,44147,44148,44149,44150,44151,44152,44153,44154,44155,44156,44157,44158,44159,44160,44161,44162,44163,44164,44165,44166,44167,44168,44169,44170,44171,44172,44173,44174,44175,44176,44177,44178,44179,44180,44181,44182,44183,44184,44185,44186,44187,44188,44189,44190,44191,44192,44193,44194,44195,44196,44197,44198,44199,44200,44201,44202,44203,44204,44205,44206,44207,44208,44209,44210,44211,44212,44213,44214,44215,44216,44217,44218,44219,44220,44221,44222,44223,44224,44225,44226,44227,44228,44229,44230,44231,44232,44233,44234,44235,44236,44237,44238,44239,44240,44241,44242,44243,44244,44245,44246,44247,44248,44249,44250,44251,44252,44253,44254,44255,44256,44257,44258,44259,44260,44261,44262,44263,44264,44265,44266,44267,44268,44269,44270,44271,44272,44273,44274,44275,44276,44277,44278,44279,44280,44281,44282,44283,44284,44285,44286,44287,44288,44289,44290,44291,44292,44293,44294,44295,44296,44297,44298,44299,44300,44301,44302,44303,44304,44305,44306,44307,44308,44309,44310,44311,44312,44313,44314,44315,44316,44317,44318,44319,44320,44321,44322,44323,44324,44325,44326,44327,44328,44329,44330,44331,44332,44333,44334,44335,44336,44337,44338,44339,44340,44341,44342,44343,44344,44345,44346,44347,44348,44349,44350,44351,44352,44353,44354,44355,44356,44357,44358,44359,44360,44361,44362,44363,44364,44365,44366,44367,44368,44369,44370,44371,44372,44373,44374,44375,44376,44377,44378,44379,44380,44381,44382,44383,44384,44385,44386,44387,44388,44389,44390,44391,44392,44393,44394,44395,44396,44397,44398,44399,44400,44401,44402,44403,44404,44405,44406,44407,44408,44409,44410,44411,44412,44413,44414,44415,44416,44417,44418,44419,44420,44421,44422,44423,44424,44425,44426,44427,44428,44429,44430,44431,44432,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,44443,44444,44445,44446,44447,44448,44449,44450,44451,44452,44453,44454,44455,44456,44457,44458,44459,44460,44461,44462,44463,44464,44465,44466,44467,44468,44469,44470,44471,44472,44473,44474,44475,44476,44477,44478,44479,44480,44481,44482,44483,44484,44485,44486,44487,44488,44489,44490,44491,44492,44493,44494,44495,44496,44497,44498,44499,44500,44501,44502,44503,44504,44505,44506,44507,44508,44509,44510,44511,44512,44513,44514,44515,44516,44517,44518,44519,44520,44521,44522,44523,44524,44525,44526,44527,44528,44529,44530,44531,44532,44533,44534,44535,44536,44537,44538,44539,44540,44541,44542,44543,44544,44545,44546,44547,44548,44549,44550,44551,44552,44553,44554,44555,44556,44557,44558,44559,44560,44561,44562,44563,44564,44565,44566,44567,44568,44569,44570,44571,44572,44573,44574,44575,44576,44577,44578,44579,44580,44581,44582,44583,44584,44585,44586,44587,44588,44589,44590,44591,44592,44593,44594,44595,44596,44597,44598,44599,44600,44601,44602,44603,44604,44605,44606,44607,44608,44609,44610,44611,44612,44613,44614,44615,44616,44617,44618,44619,44620,44621,44622,44623,44624,44625,44626,44627,44628,44629,44630,44631,44632,44633,44634,44635,44636,44637,44638,44639,44640,44641,44642,44643,44644,44645,44646,44647,44648,44649,44650,44651,44652,44653,44654,44655,44656,44657,44658,44659,44660,44661,44662,44663,44664,44665,44666,44667,44668,44669,44670,44671,44672,44673,44674,44675,44676,44677,44678,44679,44680,44681,44682,44683,44684,44685,44686,44687,44688,44689,44690,44691,44692,44693,44694,44695,44696,44697,44698,44699,44700,44701,44702,44703,44704,44705,44706,44707,44708,44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,44719,44720,44721,44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,44732,44733,44734,44735,44736,44737,44738,44739,44740,44741,44742,44743,44744,44745,44746,44747,44748,44749,44750,44751,44752,44753,44754,44755,44756,44757,44758,44759,44760,44761,44762,44763,44764,44765,44766,44767,44768,44769,44770,44771,44772,44773,44774,44775,44776,44777,44778,44779,44780,44781,44782,44783,44784,44785,44786,44787,44788,44789,44790,44791,44792,44793,44794,44795,44796,44797,44798,44799,44800,44801,44802,44803,44804,44805,44806,44807,44808,44809,44810,44811,44812,44813,44814,44815,44816,44817,44818,44819,44820,44821,44822,44823,44824,44825,44826,44827,44828,44829,44830,44831,44832,44833,44834,44835,44836,44837,44838,44839,44840,44841,44842,44843,44844,44845,44846,44847,44848,44849,44850,44851,44852,44853,44854,44855,44856,44857,44858,44859,44860,44861,44862,44863,44864,44865,44866,44867,44868,44869,44870,44871,44872,44873,44874,44875,44876,44877,44878,44879,44880,44881,44882,44883,44884,44885,44886,44887,44888,44889,44890,44891,44892,44893,44894,44895,44896,44897,44898,44899,44900,44901,44902,44903,44904,44905,44906,44907,44908,44909,44910,44911,44912,44913,44914,44915,44916,44917,44918,44919,44920,44921,44922,44923,44924,44925,44926,44927,44928,44929,44930,44931,44932,44933,44934,44935,44936,44937,44938,44939,44940,44941,44942,44943,44944,44945,44946,44947,44948,44949,44950,44951,44952,44953,44954,44955,44956,44957,44958,44959,44960,44961,44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,44972,44973,44974,44975,44976,44977,44978,44979,44980,44981,44982,44983,44984,44985,44986,44987,44988,44989,44990,44991,44992,44993,44994,44995,44996,44997,44998,44999,45000,45001,45002,45003,45004,45005,45006,45007,45008,45009,45010,45011,45012,45013,45014,45015,45016,45017,45018,45019,45020,45021,45022,45023,45024,45025,45026,45027,45028,45029,45030,45031,45032,45033,45034,45035,45036,45037,45038,45039,45040,45041,45042,45043,45044,45045,45046,45047,45048,45049,45050,45051,45052,45053,45054,45055,45056,45057,45058,45059,45060,45061,45062,45063,45064,45065,45066,45067,45068,45069,45070,45071,45072,45073,45074,45075,45076,45077,45078,45079,45080,45081,45082,45083,45084,45085,45086,45087,45088,45089,45090,45091,45092,45093,45094,45095,45096,45097,45098,45099,45100,45101,45102,45103,45104,45105,45106,45107,45108,45109,45110,45111,45112,45113,45114,45115,45116,45117,45118,45119,45120,45121,45122,45123,45124,45125,45126,45127,45128,45129,45130,45131,45132,45133,45134,45135,45136,45137,45138,45139,45140,45141,45142,45143,45144,45145,45146,45147,45148,45149,45150,45151,45152,45153,45154,45155,45156,45157,45158,45159,45160,45161,45162,45163,45164,45165,45166,45167,45168,45169,45170,45171,45172,45173,45174,45175,45176,45177,45178,45179,45180,45181,45182,45183,45184,45185,45186,45187,45188,45189,45190,45191,45192,45193,45194,45195,45196,45197,45198,45199,45200,45201,45202,45203,45204,45205,45206,45207,45208,45209,45210,45211,45212,45213,45214,45215,45216,45217,45218,45219,45220,45221,45222,45223,45224,45225,45226,45227,45228,45229,45230,45231,45232,45233,45234,45235,45236,45237,45238,45239,45240,45241,45242,45243,45244,45245,45246,45247,45248,45249,45250,45251,45252,45253,45254,45255,45256,45257,45258,45259,45260,45261,45262,45263,45264,45265,45266,45267,45268,45269,45270,45271,45272,45273,45274,45275,45276,45277,45278,45279,45280,45281,45282,45283,45284,45285,45286,45287,45288,45289,45290,45291,45292,45293,45294,45295,45296,45297,45298,45299,45300,45301,45302,45303,45304,45305,45306,45307,45308,45309,45310,45311,45312,45313,45314,45315,45316,45317,45318,45319,45320,45321,45322,45323,45324,45325,45326,45327,45328,45329,45330,45331,45332,45333,45334,45335,45336,45337,45338,45339,45340,45341,45342,45343,45344,45345,45346,45347,45348,45349,45350,45351,45352,45353,45354,45355,45356,45357,45358,45359,45360,45361,45362,45363,45364,45365,45366,45367,45368,45369,45370,45371,45372,45373,45374,45375,45376,45377,45378,45379,45380,45381,45382,45383,45384,45385,45386,45387,45388,45389,45390,45391,45392,45393,45394,45395,45396,45397,45398,45399,45400,45401,45402,45403,45404,45405,45406,45407,45408,45409,45410,45411,45412,45413,45414,45415,45416,45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,45427,45428,45429,45430,45431,45432,45433,45434,45435,45436,45437,45438,45439,45440,45441,45442,45443,45444,45445,45446,45447,45448,45449,45450,45451,45452,45453,45454,45455,45456,45457,45458,45459,45460,45461,45462,45463,45464,45465,45466,45467,45468,45469,45470,45471,45472,45473,45474,45475,45476,45477,45478,45479,45480,45481,45482,45483,45484,45485,45486,45487,45488,45489,45490,45491,45492,45493,45494,45495,45496,45497,45498,45499,45500,45501,45502,45503,45504,45505,45506,45507,45508,45509,45510,45511,45512,45513,45514,45515,45516,45517,45518,45519,45520,45521,45522,45523,45524,45525,45526,45527,45528,45529,45530,45531,45532,45533,45534,45535,45536,45537,45538,45539,45540,45541,45542,45543,45544,45545,45546,45547,45548,45549,45550,45551,45552,45553,45554,45555,45556,45557,45558,45559,45560,45561,45562,45563,45564,45565,45566,45567,45568,45569,45570,45571,45572,45573,45574,45575,45576,45577,45578,45579,45580,45581,45582,45583,45584,45585,45586,45587,45588,45589,45590,45591,45592,45593,45594,45595,45596,45597,45598,45599,45600,45601,45602,45603,45604,45605,45606,45607,45608,45609,45610,45611,45612,45613,45614,45615,45616,45617,45618,45619,45620,45621,45622,45623,45624,45625,45626,45627,45628,45629,45630,45631,45632,45633,45634,45635,45636,45637,45638,45639,45640,45641,45642,45643,45644,45645,45646,45647,45648,45649,45650,45651,45652,45653,45654,45655,45656,45657,45658,45659,45660,45661,45662,45663,45664,45665,45666,45667,45668,45669,45670,45671,45672,45673,45674,45675,45676,45677,45678,45679,45680,45681,45682,45683,45684,45685,45686,45687,45688,45689,45690,45691,45692,45693,45694,45695,45696,45697,45698,45699,45700,45701,45702,45703,45704,45705,45706,45707,45708,45709,45710,45711,45712,45713,45714,45715,45716,45717,45718,45719,45720,45721,45722,45723,45724,45725,45726,45727,45728,45729,45730,45731,45732,45733,45734,45735,45736,45737,45738,45739,45740,45741,45742,45743,45744,45745,45746,45747,45748,45749,45750,45751,45752,45753,45754,45755,45756,45757,45758,45759,45760,45761,45762,45763,45764,45765,45766,45767,45768,45769,45770,45771,45772,45773,45774,45775,45776,45777,45778,45779,45780,45781,45782,45783,45784,45785,45786,45787,45788,45789,45790,45791,45792,45793,45794,45795,45796,45797,45798,45799,45800,45801,45802,45803,45804,45805,45806,45807,45808,45809,45810,45811,45812,45813,45814,45815,45816,45817,45818,45819,45820,45821,45822,45823,45824,45825,45826,45827,45828,45829,45830,45831,45832,45833,45834,45835,45836,45837,45838,45839,45840,45841,45842,45843,45844,45845,45846,45847,45848,45849,45850,45851,45852,45853,45854,45855,45856,45857,45858,45859,45860,45861,45862,45863,45864,45865,45866,45867,45868,45869,45870,45871,45872,45873,45874,45875,45876,45877,45878,45879,45880,45881,45882,45883,45884,45885,45886,45887,45888,45889,45890,45891,45892,45893,45894,45895,45896,45897,45898,45899,45900,45901,45902,45903,45904,45905,45906,45907,45908,45909,45910,45911,45912,45913,45914,45915,45916,45917,45918,45919,45920,45921,45922,45923,45924,45925,45926,45927,45928,45929,45930,45931,45932,45933,45934,45935,45936,45937,45938,45939,45940,45941,45942,45943,45944,45945,45946,45947,45948,45949,45950,45951,45952,45953,45954,45955,45956,45957,45958,45959,45960,45961,45962,45963,45964,45965,45966,45967,45968,45969,45970,45971,45972,45973,45974,45975,45976,45977,45978,45979,45980,45981,45982,45983,45984,45985,45986,45987,45988,45989,45990,45991,45992,45993,45994,45995,45996,45997,45998,45999,46000,46001,46002,46003,46004,46005,46006,46007,46008,46009,46010,46011,46012,46013,46014,46015,46016,46017,46018,46019,46020,46021,46022,46023,46024,46025,46026,46027,46028,46029,46030,46031,46032,46033,46034,46035,46036,46037,46038,46039,46040,46041,46042,46043,46044,46045,46046,46047,46048,46049,46050,46051,46052,46053,46054,46055,46056,46057,46058,46059,46060,46061,46062,46063,46064,46065,46066,46067,46068,46069,46070,46071,46072,46073,46074,46075,46076,46077,46078,46079,46080,46081,46082,46083,46084,46085,46086,46087,46088,46089,46090,46091,46092,46093,46094,46095,46096,46097,46098,46099,46100,46101,46102,46103,46104,46105,46106,46107,46108,46109,46110,46111,46112,46113,46114,46115,46116,46117,46118,46119,46120,46121,46122,46123,46124,46125,46126,46127,46128,46129,46130,46131,46132,46133,46134,46135,46136,46137,46138,46139,46140,46141,46142,46143,46144,46145,46146,46147,46148,46149,46150,46151,46152,46153,46154,46155,46156,46157,46158,46159,46160,46161,46162,46163,46164,46165,46166,46167,46168,46169,46170,46171,46172,46173,46174,46175,46176,46177,46178,46179,46180,46181,46182,46183,46184,46185,46186,46187,46188,46189,46190,46191,46192,46193,46194,46195,46196,46197,46198,46199,46200,46201,46202,46203,46204,46205,46206,46207,46208,46209,46210,46211,46212,46213,46214,46215,46216,46217,46218,46219,46220,46221,46222,46223,46224,46225,46226,46227,46228,46229,46230,46231,46232,46233,46234,46235,46236,46237,46238,46239,46240,46241,46242,46243,46244,46245,46246,46247,46248,46249,46250,46251,46252,46253,46254,46255,46256,46257,46258,46259,46260,46261,46262,46263,46264,46265,46266,46267,46268,46269,46270,46271,46272,46273,46274,46275,46276,46277,46278,46279,46280,46281,46282,46283,46284,46285,46286,46287,46288,46289,46290,46291,46292,46293,46294,46295,46296,46297,46298,46299,46300,46301,46302,46303,46304,46305,46306,46307,46308,46309,46310,46311,46312,46313,46314,46315,46316,46317,46318,46319,46320,46321,46322,46323,46324,46325,46326,46327,46328,46329,46330,46331,46332,46333,46334,46335,46336,46337,46338,46339,46340,46341,46342,46343,46344,46345,46346,46347,46348,46349,46350,46351,46352,46353,46354,46355,46356,46357,46358,46359,46360,46361,46362,46363,46364,46365,46366,46367,46368,46369,46370,46371,46372,46373,46374,46375,46376,46377,46378,46379,46380,46381,46382,46383,46384,46385,46386,46387,46388,46389,46390,46391,46392,46393,46394,46395,46396,46397,46398,46399,46400,46401,46402,46403,46404,46405,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,46416,46417,46418,46419,46420,46421,46422,46423,46424,46425,46426,46427,46428,46429,46430,46431,46432,46433,46434,46435,46436,46437,46438,46439,46440,46441,46442,46443,46444,46445,46446,46447,46448,46449,46450,46451,46452,46453,46454,46455,46456,46457,46458,46459,46460,46461,46462,46463,46464,46465,46466,46467,46468,46469,46470,46471,46472,46473,46474,46475,46476,46477,46478,46479,46480,46481,46482,46483,46484,46485,46486,46487,46488,46489,46490,46491,46492,46493,46494,46495,46496,46497,46498,46499,46500,46501,46502,46503,46504,46505,46506,46507,46508,46509,46510,46511,46512,46513,46514,46515,46516,46517,46518,46519,46520,46521,46522,46523,46524,46525,46526,46527,46528,46529,46530,46531,46532,46533,46534,46535,46536,46537,46538,46539,46540,46541,46542,46543,46544,46545,46546,46547,46548,46549,46550,46551,46552,46553,46554,46555,46556,46557,46558,46559,46560,46561,46562,46563,46564,46565,46566,46567,46568,46569,46570,46571,46572,46573,46574,46575,46576,46577,46578,46579,46580,46581,46582,46583,46584,46585,46586,46587,46588,46589,46590,46591,46592,46593,46594,46595,46596,46597,46598,46599,46600,46601,46602,46603,46604,46605,46606,46607,46608,46609,46610,46611,46612,46613,46614,46615,46616,46617,46618,46619,46620,46621,46622,46623,46624,46625,46626,46627,46628,46629,46630,46631,46632,46633,46634,46635,46636,46637,46638,46639,46640,46641,46642,46643,46644,46645,46646,46647,46648,46649,46650,46651,46652,46653,46654,46655,46656,46657,46658,46659,46660,46661,46662,46663,46664,46665,46666,46667,46668,46669,46670,46671,46672,46673,46674,46675,46676,46677,46678,46679,46680,46681,46682,46683,46684,46685,46686,46687,46688,46689,46690,46691,46692,46693,46694,46695,46696,46697,46698,46699,46700,46701,46702,46703,46704,46705,46706,46707,46708,46709,46710,46711,46712,46713,46714,46715,46716,46717,46718,46719,46720,46721,46722,46723,46724,46725,46726,46727,46728,46729,46730,46731,46732,46733,46734,46735,46736,46737,46738,46739,46740,46741,46742,46743,46744,46745,46746,46747,46748,46749,46750,46751,46752,46753,46754,46755,46756,46757,46758,46759,46760,46761,46762,46763,46764,46765,46766,46767,46768,46769,46770,46771,46772,46773,46774,46775,46776,46777,46778,46779,46780,46781,46782,46783,46784,46785,46786,46787,46788,46789,46790,46791,46792,46793,46794,46795,46796,46797,46798,46799,46800,46801,46802,46803,46804,46805,46806,46807,46808,46809,46810,46811,46812,46813,46814,46815,46816,46817,46818,46819,46820,46821,46822,46823,46824,46825,46826,46827,46828,46829,46830,46831,46832,46833,46834,46835,46836,46837,46838,46839,46840,46841,46842,46843,46844,46845,46846,46847,46848,46849,46850,46851,46852,46853,46854,46855,46856,46857,46858,46859,46860,46861,46862,46863,46864,46865,46866,46867,46868,46869,46870,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880,46881,46882,46883,46884,46885,46886,46887,46888,46889,46890,46891,46892,46893,46894,46895,46896,46897,46898,46899,46900,46901,46902,46903,46904,46905,46906,46907,46908,46909,46910,46911,46912,46913,46914,46915,46916,46917,46918,46919,46920,46921,46922,46923,46924,46925,46926,46927,46928,46929,46930,46931,46932,46933,46934,46935,46936,46937,46938,46939,46940,46941,46942,46943,46944,46945,46946,46947,46948,46949,46950,46951,46952,46953,46954,46955,46956,46957,46958,46959,46960,46961,46962,46963,46964,46965,46966,46967,46968,46969,46970,46971,46972,46973,46974,46975,46976,46977,46978,46979,46980,46981,46982,46983,46984,46985,46986,46987,46988,46989,46990,46991,46992,46993,46994,46995,46996,46997,46998,46999,47000,47001,47002,47003,47004,47005,47006,47007,47008,47009,47010,47011,47012,47013,47014,47015,47016,47017,47018,47019,47020,47021,47022,47023,47024,47025,47026,47027,47028,47029,47030,47031,47032,47033,47034,47035,47036,47037,47038,47039,47040,47041,47042,47043,47044,47045,47046,47047,47048,47049,47050,47051,47052,47053,47054,47055,47056,47057,47058,47059,47060,47061,47062,47063,47064,47065,47066,47067,47068,47069,47070,47071,47072,47073,47074,47075,47076,47077,47078,47079,47080,47081,47082,47083,47084,47085,47086,47087,47088,47089,47090,47091,47092,47093,47094,47095,47096,47097,47098,47099,47100,47101,47102,47103,47104,47105,47106,47107,47108,47109,47110,47111,47112,47113,47114,47115,47116,47117,47118,47119,47120,47121,47122,47123,47124,47125,47126,47127,47128,47129,47130,47131,47132,47133,47134,47135,47136,47137,47138,47139,47140,47141,47142,47143,47144,47145,47146,47147,47148,47149,47150,47151,47152,47153,47154,47155,47156,47157,47158,47159,47160,47161,47162,47163,47164,47165,47166,47167,47168,47169,47170,47171,47172,47173,47174,47175,47176,47177,47178,47179,47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,47190,47191,47192,47193,47194,47195,47196,47197,47198,47199,47200,47201,47202,47203,47204,47205,47206,47207,47208,47209,47210,47211,47212,47213,47214,47215,47216,47217,47218,47219,47220,47221,47222,47223,47224,47225,47226,47227,47228,47229,47230,47231,47232,47233,47234,47235,47236,47237,47238,47239,47240,47241,47242,47243,47244,47245,47246,47247,47248,47249,47250,47251,47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,47264,47265,47266,47267,47268,47269,47270,47271,47272,47273,47274,47275,47276,47277,47278,47279,47280,47281,47282,47283,47284,47285,47286,47287,47288,47289,47290,47291,47292,47293,47294,47295,47296,47297,47298,47299,47300,47301,47302,47303,47304,47305,47306,47307,47308,47309,47310,47311,47312,47313,47314,47315,47316,47317,47318,47319,47320,47321,47322,47323,47324,47325,47326,47327,47328,47329,47330,47331,47332,47333,47334,47335,47336,47337,47338,47339,47340,47341,47342,47343,47344,47345,47346,47347,47348,47349,47350,47351,47352,47353,47354,47355,47356,47357,47358,47359,47360,47361,47362,47363,47364,47365,47366,47367,47368,47369,47370,47371,47372,47373,47374,47375,47376,47377,47378,47379,47380,47381,47382,47383,47384,47385,47386,47387,47388,47389,47390,47391,47392,47393,47394,47395,47396,47397,47398,47399,47400,47401,47402,47403,47404,47405,47406,47407,47408,47409,47410,47411,47412,47413,47414,47415,47416,47417,47418,47419,47420,47421,47422,47423,47424,47425,47426,47427,47428,47429,47430,47431,47432,47433,47434,47435,47436,47437,47438,47439,47440,47441,47442,47443,47444,47445,47446,47447,47448,47449,47450,47451,47452,47453,47454,47455,47456,47457,47458,47459,47460,47461,47462,47463,47464,47465,47466,47467,47468,47469,47470,47471,47472,47473,47474,47475,47476,47477,47478,47479,47480,47481,47482,47483,47484,47485,47486,47487,47488,47489,47490,47491,47492,47493,47494,47495,47496,47497,47498,47499,47500,47501,47502,47503,47504,47505,47506,47507,47508,47509,47510,47511,47512,47513,47514,47515,47516,47517,47518,47519,47520,47521,47522,47523,47524,47525,47526,47527,47528,47529,47530,47531,47532,47533,47534,47535,47536,47537,47538,47539,47540,47541,47542,47543,47544,47545,47546,47547,47548,47549,47550,47551,47552,47553,47554,47555,47556,47557,47558,47559,47560,47561,47562,47563,47564,47565,47566,47567,47568,47569,47570,47571,47572,47573,47574,47575,47576,47577,47578,47579,47580,47581,47582,47583,47584,47585,47586,47587,47588,47589,47590,47591,47592,47593,47594,47595,47596,47597,47598,47599,47600,47601,47602,47603,47604,47605,47606,47607,47608,47609,47610,47611,47612,47613,47614,47615,47616,47617,47618,47619,47620,47621,47622,47623,47624,47625,47626,47627,47628,47629,47630,47631,47632,47633,47634,47635,47636,47637,47638,47639,47640,47641,47642,47643,47644,47645,47646,47647,47648,47649,47650,47651,47652,47653,47654,47655,47656,47657,47658,47659,47660,47661,47662,47663,47664,47665,47666,47667,47668,47669,47670,47671,47672,47673,47674,47675,47676,47677,47678,47679,47680,47681,47682,47683,47684,47685,47686,47687,47688,47689,47690,47691,47692,47693,47694,47695,47696,47697,47698,47699,47700,47701,47702,47703,47704,47705,47706,47707,47708,47709,47710,47711,47712,47713,47714,47715,47716,47717,47718,47719,47720,47721,47722,47723,47724,47725,47726,47727,47728,47729,47730,47731,47732,47733,47734,47735,47736,47737,47738,47739,47740,47741,47742,47743,47744,47745,47746,47747,47748,47749,47750,47751,47752,47753,47754,47755,47756,47757,47758,47759,47760,47761,47762,47763,47764,47765,47766,47767,47768,47769,47770,47771,47772,47773,47774,47775,47776,47777,47778,47779,47780,47781,47782,47783,47784,47785,47786,47787,47788,47789,47790,47791,47792,47793,47794,47795,47796,47797,47798,47799,47800,47801,47802,47803,47804,47805,47806,47807,47808,47809,47810,47811,47812,47813,47814,47815,47816,47817,47818,47819,47820,47821,47822,47823,47824,47825,47826,47827,47828,47829,47830,47831,47832,47833,47834,47835,47836,47837,47838,47839,47840,47841,47842,47843,47844,47845,47846,47847,47848,47849,47850,47851,47852,47853,47854,47855,47856,47857,47858,47859,47860,47861,47862,47863,47864,47865,47866,47867,47868,47869,47870,47871,47872,47873,47874,47875,47876,47877,47878,47879,47880,47881,47882,47883,47884,47885,47886,47887,47888,47889,47890,47891,47892,47893,47894,47895,47896,47897,47898,47899,47900,47901,47902,47903,47904,47905,47906,47907,47908,47909,47910,47911,47912,47913,47914,47915,47916,47917,47918,47919,47920,47921,47922,47923,47924,47925,47926,47927,47928,47929,47930,47931,47932,47933,47934,47935,47936,47937,47938,47939,47940,47941,47942,47943,47944,47945,47946,47947,47948,47949,47950,47951,47952,47953,47954,47955,47956,47957,47958,47959,47960,47961,47962,47963,47964,47965,47966,47967,47968,47969,47970,47971,47972,47973,47974,47975,47976,47977,47978,47979,47980,47981,47982,47983,47984,47985,47986,47987,47988,47989,47990,47991,47992,47993,47994,47995,47996,47997,47998,47999,48000,48001,48002,48003,48004,48005,48006,48007,48008,48009,48010,48011,48012,48013,48014,48015,48016,48017,48018,48019,48020,48021,48022,48023,48024,48025,48026,48027,48028,48029,48030,48031,48032,48033,48034,48035,48036,48037,48038,48039,48040,48041,48042,48043,48044,48045,48046,48047,48048,48049,48050,48051,48052,48053,48054,48055,48056,48057,48058,48059,48060,48061,48062,48063,48064,48065,48066,48067,48068,48069,48070,48071,48072,48073,48074,48075,48076,48077,48078,48079,48080,48081,48082,48083,48084,48085,48086,48087,48088,48089,48090,48091,48092,48093,48094,48095,48096,48097,48098,48099,48100,48101,48102,48103,48104,48105,48106,48107,48108,48109,48110,48111,48112,48113,48114,48115,48116,48117,48118,48119,48120,48121,48122,48123,48124,48125,48126,48127,48128,48129,48130,48131,48132,48133,48134,48135,48136,48137,48138,48139,48140,48141,48142,48143,48144,48145,48146,48147,48148,48149,48150,48151,48152,48153,48154,48155,48156,48157,48158,48159,48160,48161,48162,48163,48164,48165,48166,48167,48168,48169,48170,48171,48172,48173,48174,48175,48176,48177,48178,48179,48180,48181,48182,48183,48184,48185,48186,48187,48188,48189,48190,48191,48192,48193,48194,48195,48196,48197,48198,48199,48200,48201,48202,48203,48204,48205,48206,48207,48208,48209,48210,48211,48212,48213,48214,48215,48216,48217,48218,48219,48220,48221,48222,48223,48224,48225,48226,48227,48228,48229,48230,48231,48232,48233,48234,48235,48236,48237,48238,48239,48240,48241,48242,48243,48244,48245,48246,48247,48248,48249,48250,48251,48252,48253,48254,48255,48256,48257,48258,48259,48260,48261,48262,48263,48264,48265,48266,48267,48268,48269,48270,48271,48272,48273,48274,48275,48276,48277,48278,48279,48280,48281,48282,48283,48284,48285,48286,48287,48288,48289,48290,48291,48292,48293,48294,48295,48296,48297,48298,48299,48300,48301,48302,48303,48304,48305,48306,48307,48308,48309,48310,48311,48312,48313,48314,48315,48316,48317,48318,48319,48320,48321,48322,48323,48324,48325,48326,48327,48328,48329,48330,48331,48332,48333,48334,48335,48336,48337,48338,48339,48340,48341,48342,48343,48344,48345,48346,48347,48348,48349,48350,48351,48352,48353,48354,48355,48356,48357,48358,48359,48360,48361,48362,48363,48364,48365,48366,48367,48368,48369,48370,48371,48372,48373,48374,48375,48376,48377,48378,48379,48380,48381,48382,48383,48384,48385,48386,48387,48388,48389,48390,48391,48392,48393,48394,48395,48396,48397,48398,48399,48400,48401,48402,48403,48404,48405,48406,48407,48408,48409,48410,48411,48412,48413,48414,48415,48416,48417,48418,48419,48420,48421,48422,48423,48424,48425,48426,48427,48428,48429,48430,48431,48432,48433,48434,48435,48436,48437,48438,48439,48440,48441,48442,48443,48444,48445,48446,48447,48448,48449,48450,48451,48452,48453,48454,48455,48456,48457,48458,48459,48460,48461,48462,48463,48464,48465,48466,48467,48468,48469,48470,48471,48472,48473,48474,48475,48476,48477,48478,48479,48480,48481,48482,48483,48484,48485,48486,48487,48488,48489,48490,48491,48492,48493,48494,48495,48496,48497,48498,48499,48500,48501,48502,48503,48504,48505,48506,48507,48508,48509,48510,48511,48512,48513,48514,48515,48516,48517,48518,48519,48520,48521,48522,48523,48524,48525,48526,48527,48528,48529,48530,48531,48532,48533,48534,48535,48536,48537,48538,48539,48540,48541,48542,48543,48544,48545,48546,48547,48548,48549,48550,48551,48552,48553,48554,48555,48556,48557,48558,48559,48560,48561,48562,48563,48564,48565,48566,48567,48568,48569,48570,48571,48572,48573,48574,48575,48576,48577,48578,48579,48580,48581,48582,48583,48584,48585,48586,48587,48588,48589,48590,48591,48592,48593,48594,48595,48596,48597,48598,48599,48600,48601,48602,48603,48604,48605,48606,48607,48608,48609,48610,48611,48612,48613,48614,48615,48616,48617,48618,48619,48620,48621,48622,48623,48624,48625,48626,48627,48628,48629,48630,48631,48632,48633,48634,48635,48636,48637,48638,48639,48640,48641,48642,48643,48644,48645,48646,48647,48648,48649,48650,48651,48652,48653,48654,48655,48656,48657,48658,48659,48660,48661,48662,48663,48664,48665,48666,48667,48668,48669,48670,48671,48672,48673,48674,48675,48676,48677,48678,48679,48680,48681,48682,48683,48684,48685,48686,48687,48688,48689,48690,48691,48692,48693,48694,48695,48696,48697,48698,48699,48700,48701,48702,48703,48704,48705,48706,48707,48708,48709,48710,48711,48712,48713,48714,48715,48716,48717,48718,48719,48720,48721,48722,48723,48724,48725,48726,48727,48728,48729,48730,48731,48732,48733,48734,48735,48736,48737,48738,48739,48740,48741,48742,48743,48744,48745,48746,48747,48748,48749,48750,48751,48752,48753,48754,48755,48756,48757,48758,48759,48760,48761,48762,48763,48764,48765,48766,48767,48768,48769,48770,48771,48772,48773,48774,48775,48776,48777,48778,48779,48780,48781,48782,48783,48784,48785,48786,48787,48788,48789,48790,48791,48792,48793,48794,48795,48796,48797,48798,48799,48800,48801,48802,48803,48804,48805,48806,48807,48808,48809,48810,48811,48812,48813,48814,48815,48816,48817,48818,48819,48820,48821,48822,48823,48824,48825,48826,48827,48828,48829,48830,48831,48832,48833,48834,48835,48836,48837,48838,48839,48840,48841,48842,48843,48844,48845,48846,48847,48848,48849,48850,48851,48852,48853,48854,48855,48856,48857,48858,48859,48860,48861,48862,48863,48864,48865,48866,48867,48868,48869,48870,48871,48872,48873,48874,48875,48876,48877,48878,48879,48880,48881,48882,48883,48884,48885,48886,48887,48888,48889,48890,48891,48892,48893,48894,48895,48896,48897,48898,48899,48900,48901,48902,48903,48904,48905,48906,48907,48908,48909,48910,48911,48912,48913,48914,48915,48916,48917,48918,48919,48920,48921,48922,48923,48924,48925,48926,48927,48928,48929,48930,48931,48932,48933,48934,48935,48936,48937,48938,48939,48940,48941,48942,48943,48944,48945,48946,48947,48948,48949,48950,48951,48952,48953,48954,48955,48956,48957,48958,48959,48960,48961,48962,48963,48964,48965,48966,48967,48968,48969,48970,48971,48972,48973,48974,48975,48976,48977,48978,48979,48980,48981,48982,48983,48984,48985,48986,48987,48988,48989,48990,48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,49014,49015,49016,49017,49018,49019,49020,49021,49022,49023,49024,49025,49026,49027,49028,49029,49030,49031,49032,49033,49034,49035,49036,49037,49038,49039,49040,49041,49042,49043,49044,49045,49046,49047,49048,49049,49050,49051,49052,49053,49054,49055,49056,49057,49058,49059,49060,49061,49062,49063,49064,49065,49066,49067,49068,49069,49070,49071,49072,49073,49074,49075,49076,49077,49078,49079,49080,49081,49082,49083,49084,49085,49086,49087,49088,49089,49090,49091,49092,49093,49094,49095,49096,49097,49098,49099,49100,49101,49102,49103,49104,49105,49106,49107,49108,49109,49110,49111,49112,49113,49114,49115,49116,49117,49118,49119,49120,49121,49122,49123,49124,49125,49126,49127,49128,49129,49130,49131,49132,49133,49134,49135,49136,49137,49138,49139,49140,49141,49142,49143,49144,49145,49146,49147,49148,49149,49150,49151,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49162,49163,49164,49165,49166,49167,49168,49169,49170,49171,49172,49173,49174,49175,49176,49177,49178,49179,49180,49181,49182,49183,49184,49185,49186,49187,49188,49189,49190,49191,49192,49193,49194,49195,49196,49197,49198,49199,49200,49201,49202,49203,49204,49205,49206,49207,49208,49209,49210,49211,49212,49213,49214,49215,49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,49226,49227,49228,49229,49230,49231,49232,49233,49234,49235,49236,49237,49238,49239,49240,49241,49242,49243,49244,49245,49246,49247,49248,49249,49250,49251,49252,49253,49254,49255,49256,49257,49258,49259,49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,49272,49273,49274,49275,49276,49277,49278,49279,49280,49281,49282,49283,49284,49285,49286,49287,49288,49289,49290,49291,49292,49293,49294,49295,49296,49297,49298,49299,49300,49301,49302,49303,49304,49305,49306,49307,49308,49309,49310,49311,49312,49313,49314,49315,49316,49317,49318,49319,49320,49321,49322,49323,49324,49325,49326,49327,49328,49329,49330,49331,49332,49333,49334,49335,49336,49337,49338,49339,49340,49341,49342,49343,49344,49345,49346,49347,49348,49349,49350,49351,49352,49353,49354,49355,49356,49357,49358,49359,49360,49361,49362,49363,49364,49365,49366,49367,49368,49369,49370,49371,49372,49373,49374,49375,49376,49377,49378,49379,49380,49381,49382,49383,49384,49385,49386,49387,49388,49389,49390,49391,49392,49393,49394,49395,49396,49397,49398,49399,49400,49401,49402,49403,49404,49405,49406,49407,49408,49409,49410,49411,49412,49413,49414,49415,49416,49417,49418,49419,49420,49421,49422,49423,49424,49425,49426,49427,49428,49429,49430,49431,49432,49433,49434,49435,49436,49437,49438,49439,49440,49441,49442,49443,49444,49445,49446,49447,49448,49449,49450,49451,49452,49453,49454,49455,49456,49457,49458,49459,49460,49461,49462,49463,49464,49465,49466,49467,49468,49469,49470,49471,49472,49473,49474,49475,49476,49477,49478,49479,49480,49481,49482,49483,49484,49485,49486,49487,49488,49489,49490,49491,49492,49493,49494,49495,49496,49497,49498,49499,49500,49501,49502,49503,49504,49505,49506,49507,49508,49509,49510,49511,49512,49513,49514,49515,49516,49517,49518,49519,49520,49521,49522,49523,49524,49525,49526,49527,49528,49529,49530,49531,49532,49533,49534,49535,49536,49537,49538,49539,49540,49541,49542,49543,49544,49545,49546,49547,49548,49549,49550,49551,49552,49553,49554,49555,49556,49557,49558,49559,49560,49561,49562,49563,49564,49565,49566,49567,49568,49569,49570,49571,49572,49573,49574,49575,49576,49577,49578,49579,49580,49581,49582,49583,49584,49585,49586,49587,49588,49589,49590,49591,49592,49593,49594,49595,49596,49597,49598,49599,49600,49601,49602,49603,49604,49605,49606,49607,49608,49609,49610,49611,49612,49613,49614,49615,49616,49617,49618,49619,49620,49621,49622,49623,49624,49625,49626,49627,49628,49629,49630,49631,49632,49633,49634,49635,49636,49637,49638,49639,49640,49641,49642,49643,49644,49645,49646,49647,49648,49649,49650,49651,49652,49653,49654,49655,49656,49657,49658,49659,49660,49661,49662,49663,49664,49665,49666,49667,49668,49669,49670,49671,49672,49673,49674,49675,49676,49677,49678,49679,49680,49681,49682,49683,49684,49685,49686,49687,49688,49689,49690,49691,49692,49693,49694,49695,49696,49697,49698,49699,49700,49701,49702,49703,49704,49705,49706,49707,49708,49709,49710,49711,49712,49713,49714,49715,49716,49717,49718,49719,49720,49721,49722,49723,49724,49725,49726,49727,49728,49729,49730,49731,49732,49733,49734,49735,49736,49737,49738,49739,49740,49741,49742,49743,49744,49745,49746,49747,49748,49749,49750,49751,49752,49753,49754,49755,49756,49757,49758,49759,49760,49761,49762,49763,49764,49765,49766,49767,49768,49769,49770,49771,49772,49773,49774,49775,49776,49777,49778,49779,49780,49781,49782,49783,49784,49785,49786,49787,49788,49789,49790,49791,49792,49793,49794,49795,49796,49797,49798,49799,49800,49801,49802,49803,49804,49805,49806,49807,49808,49809,49810,49811,49812,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,49823,49824,49825,49826,49827,49828,49829,49830,49831,49832,49833,49834,49835,49836,49837,49838,49839,49840,49841,49842,49843,49844,49845,49846,49847,49848,49849,49850,49851,49852,49853,49854,49855,49856,49857,49858,49859,49860,49861,49862,49863,49864,49865,49866,49867,49868,49869,49870,49871,49872,49873,49874,49875,49876,49877,49878,49879,49880,49881,49882,49883,49884,49885,49886,49887,49888,49889,49890,49891,49892,49893,49894,49895,49896,49897,49898,49899,49900,49901,49902,49903,49904,49905,49906,49907,49908,49909,49910,49911,49912,49913,49914,49915,49916,49917,49918,49919,49920,49921,49922,49923,49924,49925,49926,49927,49928,49929,49930,49931,49932,49933,49934,49935,49936,49937,49938,49939,49940,49941,49942,49943,49944,49945,49946,49947,49948,49949,49950,49951,49952,49953,49954,49955,49956,49957,49958,49959,49960,49961,49962,49963,49964,49965,49966,49967,49968,49969,49970,49971,49972,49973,49974,49975,49976,49977,49978,49979,49980,49981,49982,49983,49984,49985,49986,49987,49988,49989,49990,49991,49992,49993,49994,49995,49996,49997,49998,49999,50000,50001,50002,50003,50004,50005,50006,50007,50008,50009,50010,50011,50012,50013,50014,50015,50016,50017,50018,50019,50020,50021,50022,50023,50024,50025,50026,50027,50028,50029,50030,50031,50032,50033,50034,50035,50036,50037,50038,50039,50040,50041,50042,50043,50044,50045,50046,50047,50048,50049,50050,50051,50052,50053,50054,50055,50056,50057,50058,50059,50060,50061,50062,50063,50064,50065,50066,50067,50068,50069,50070,50071,50072,50073,50074,50075,50076,50077,50078,50079,50080,50081,50082,50083,50084,50085,50086,50087,50088,50089,50090,50091,50092,50093,50094,50095,50096,50097,50098,50099,50100,50101,50102,50103,50104,50105,50106,50107,50108,50109,50110,50111,50112,50113,50114,50115,50116,50117,50118,50119,50120,50121,50122,50123,50124,50125,50126,50127,50128,50129,50130,50131,50132,50133,50134,50135,50136,50137,50138,50139,50140,50141,50142,50143,50144,50145,50146,50147,50148,50149,50150,50151,50152,50153,50154,50155,50156,50157,50158,50159,50160,50161,50162,50163,50164,50165,50166,50167,50168,50169,50170,50171,50172,50173,50174,50175,50176,50177,50178,50179,50180,50181,50182,50183,50184,50185,50186,50187,50188,50189,50190,50191,50192,50193,50194,50195,50196,50197,50198,50199,50200,50201,50202,50203,50204,50205,50206,50207,50208,50209,50210,50211,50212,50213,50214,50215,50216,50217,50218,50219,50220,50221,50222,50223,50224,50225,50226,50227,50228,50229,50230,50231,50232,50233,50234,50235,50236,50237,50238,50239,50240,50241,50242,50243,50244,50245,50246,50247,50248,50249,50250,50251,50252,50253,50254,50255,50256,50257,50258,50259,50260,50261,50262,50263,50264,50265,50266,50267,50268,50269,50270,50271,50272,50273,50274,50275,50276,50277,50278,50279,50280,50281,50282,50283,50284,50285,50286,50287,50288,50289,50290,50291,50292,50293,50294,50295,50296,50297,50298,50299,50300,50301,50302,50303,50304,50305,50306,50307,50308,50309,50310,50311,50312,50313,50314,50315,50316,50317,50318,50319,50320,50321,50322,50323,50324,50325,50326,50327,50328,50329,50330,50331,50332,50333,50334,50335,50336,50337,50338,50339,50340,50341,50342,50343,50344,50345,50346,50347,50348,50349,50350,50351,50352,50353,50354,50355,50356,50357,50358,50359,50360,50361,50362,50363,50364,50365,50366,50367,50368,50369,50370,50371,50372,50373,50374,50375,50376,50377,50378,50379,50380,50381,50382,50383,50384,50385,50386,50387,50388,50389,50390,50391,50392,50393,50394,50395,50396,50397,50398,50399,50400,50401,50402,50403,50404,50405,50406,50407,50408,50409,50410,50411,50412,50413,50414,50415,50416,50417,50418,50419,50420,50421,50422,50423,50424,50425,50426,50427,50428,50429,50430,50431,50432,50433,50434,50435,50436,50437,50438,50439,50440,50441,50442,50443,50444,50445,50446,50447,50448,50449,50450,50451,50452,50453,50454,50455,50456,50457,50458,50459,50460,50461,50462,50463,50464,50465,50466,50467,50468,50469,50470,50471,50472,50473,50474,50475,50476,50477,50478,50479,50480,50481,50482,50483,50484,50485,50486,50487,50488,50489,50490,50491,50492,50493,50494,50495,50496,50497,50498,50499,50500,50501,50502,50503,50504,50505,50506,50507,50508,50509,50510,50511,50512,50513,50514,50515,50516,50517,50518,50519,50520,50521,50522,50523,50524,50525,50526,50527,50528,50529,50530,50531,50532,50533,50534,50535,50536,50537,50538,50539,50540,50541,50542,50543,50544,50545,50546,50547,50548,50549,50550,50551,50552,50553,50554,50555,50556,50557,50558,50559,50560,50561,50562,50563,50564,50565,50566,50567,50568,50569,50570,50571,50572,50573,50574,50575,50576,50577,50578,50579,50580,50581,50582,50583,50584,50585,50586,50587,50588,50589,50590,50591,50592,50593,50594,50595,50596,50597,50598,50599,50600,50601,50602,50603,50604,50605,50606,50607,50608,50609,50610,50611,50612,50613,50614,50615,50616,50617,50618,50619,50620,50621,50622,50623,50624,50625,50626,50627,50628,50629,50630,50631,50632,50633,50634,50635,50636,50637,50638,50639,50640,50641,50642,50643,50644,50645,50646,50647,50648,50649,50650,50651,50652,50653,50654,50655,50656,50657,50658,50659,50660,50661,50662,50663,50664,50665,50666,50667,50668,50669,50670,50671,50672,50673,50674,50675,50676,50677,50678,50679,50680,50681,50682,50683,50684,50685,50686,50687,50688,50689,50690,50691,50692,50693,50694,50695,50696,50697,50698,50699,50700,50701,50702,50703,50704,50705,50706,50707,50708,50709,50710,50711,50712,50713,50714,50715,50716,50717,50718,50719,50720,50721,50722,50723,50724,50725,50726,50727,50728,50729,50730,50731,50732,50733,50734,50735,50736,50737,50738,50739,50740,50741,50742,50743,50744,50745,50746,50747,50748,50749,50750,50751,50752,50753,50754,50755,50756,50757,50758,50759,50760,50761,50762,50763,50764,50765,50766,50767,50768,50769,50770,50771,50772,50773,50774,50775,50776,50777,50778,50779,50780,50781,50782,50783,50784,50785,50786,50787,50788,50789,50790,50791,50792,50793,50794,50795,50796,50797,50798,50799,50800,50801,50802,50803,50804,50805,50806,50807,50808,50809,50810,50811,50812,50813,50814,50815,50816,50817,50818,50819,50820,50821,50822,50823,50824,50825,50826,50827,50828,50829,50830,50831,50832,50833,50834,50835,50836,50837,50838,50839,50840,50841,50842,50843,50844,50845,50846,50847,50848,50849,50850,50851,50852,50853,50854,50855,50856,50857,50858,50859,50860,50861,50862,50863,50864,50865,50866,50867,50868,50869,50870,50871,50872,50873,50874,50875,50876,50877,50878,50879,50880,50881,50882,50883,50884,50885,50886,50887,50888,50889,50890,50891,50892,50893,50894,50895,50896,50897,50898,50899,50900,50901,50902,50903,50904,50905,50906,50907,50908,50909,50910,50911,50912,50913,50914,50915,50916,50917,50918,50919,50920,50921,50922,50923,50924,50925,50926,50927,50928,50929,50930,50931,50932,50933,50934,50935,50936,50937,50938,50939,50940,50941,50942,50943,50944,50945,50946,50947,50948,50949,50950,50951,50952,50953,50954,50955,50956,50957,50958,50959,50960,50961,50962,50963,50964,50965,50966,50967,50968,50969,50970,50971,50972,50973,50974,50975,50976,50977,50978,50979,50980,50981,50982,50983,50984,50985,50986,50987,50988,50989,50990,50991,50992,50993,50994,50995,50996,50997,50998,50999,51000,51001,51002,51003,51004,51005,51006,51007,51008,51009,51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,51022,51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,51035,51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,51048,51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,51061,51062,51063,51064,51065,51066,51067,51068,51069,51070,51071,51072,51073,51074,51075,51076,51077,51078,51079,51080,51081,51082,51083,51084,51085,51086,51087,51088,51089,51090,51091,51092,51093,51094,51095,51096,51097,51098,51099,51100,51101,51102,51103,51104,51105,51106,51107,51108,51109,51110,51111,51112,51113,51114,51115,51116,51117,51118,51119,51120,51121,51122,51123,51124,51125,51126,51127,51128,51129,51130,51131,51132,51133,51134,51135,51136,51137,51138,51139,51140,51141,51142,51143,51144,51145,51146,51147,51148,51149,51150,51151,51152,51153,51154,51155,51156,51157,51158,51159,51160,51161,51162,51163,51164,51165,51166,51167,51168,51169,51170,51171,51172,51173,51174,51175,51176,51177,51178,51179,51180,51181,51182,51183,51184,51185,51186,51187,51188,51189,51190,51191,51192,51193,51194,51195,51196,51197,51198,51199,51200,51201,51202,51203,51204,51205,51206,51207,51208,51209,51210,51211,51212,51213,51214,51215,51216,51217,51218,51219,51220,51221,51222,51223,51224,51225,51226,51227,51228,51229,51230,51231,51232,51233,51234,51235,51236,51237,51238,51239,51240,51241,51242,51243,51244,51245,51246,51247,51248,51249,51250,51251,51252,51253,51254,51255,51256,51257,51258,51259,51260,51261,51262,51263,51264,51265,51266,51267,51268,51269,51270,51271,51272,51273,51274,51275,51276,51277,51278,51279,51280,51281,51282,51283,51284,51285,51286,51287,51288,51289,51290,51291,51292,51293,51294,51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305,51306,51307,51308,51309,51310,51311,51312,51313,51314,51315,51316,51317,51318,51319,51320,51321,51322,51323,51324,51325,51326,51327,51328,51329,51330,51331,51332,51333,51334,51335,51336,51337,51338,51339,51340,51341,51342,51343,51344,51345,51346,51347,51348,51349,51350,51351,51352,51353,51354,51355,51356,51357,51358,51359,51360,51361,51362,51363,51364,51365,51366,51367,51368,51369,51370,51371,51372,51373,51374,51375,51376,51377,51378,51379,51380,51381,51382,51383,51384,51385,51386,51387,51388,51389,51390,51391,51392,51393,51394,51395,51396,51397,51398,51399,51400,51401,51402,51403,51404,51405,51406,51407,51408,51409,51410,51411,51412,51413,51414,51415,51416,51417,51418,51419,51420,51421,51422,51423,51424,51425,51426,51427,51428,51429,51430,51431,51432,51433,51434,51435,51436,51437,51438,51439,51440,51441,51442,51443,51444,51445,51446,51447,51448,51449,51450,51451,51452,51453,51454,51455,51456,51457,51458,51459,51460,51461,51462,51463,51464,51465,51466,51467,51468,51469,51470,51471,51472,51473,51474,51475,51476,51477,51478,51479,51480,51481,51482,51483,51484,51485,51486,51487,51488,51489,51490,51491,51492,51493,51494,51495,51496,51497,51498,51499,51500,51501,51502,51503,51504,51505,51506,51507,51508,51509,51510,51511,51512,51513,51514,51515,51516,51517,51518,51519,51520,51521,51522,51523,51524,51525,51526,51527,51528,51529,51530,51531,51532,51533,51534,51535,51536,51537,51538,51539,51540,51541,51542,51543,51544,51545,51546,51547,51548,51549,51550,51551,51552,51553,51554,51555,51556,51557,51558,51559,51560,51561,51562,51563,51564,51565,51566,51567,51568,51569,51570,51571,51572,51573,51574,51575,51576,51577,51578,51579,51580,51581,51582,51583,51584,51585,51586,51587,51588,51589,51590,51591,51592,51593,51594,51595,51596,51597,51598,51599,51600,51601,51602,51603,51604,51605,51606,51607,51608,51609,51610,51611,51612,51613,51614,51615,51616,51617,51618,51619,51620,51621,51622,51623,51624,51625,51626,51627,51628,51629,51630,51631,51632,51633,51634,51635,51636,51637,51638,51639,51640,51641,51642,51643,51644,51645,51646,51647,51648,51649,51650,51651,51652,51653,51654,51655,51656,51657,51658,51659,51660,51661,51662,51663,51664,51665,51666,51667,51668,51669,51670,51671,51672,51673,51674,51675,51676,51677,51678,51679,51680,51681,51682,51683,51684,51685,51686,51687,51688,51689,51690,51691,51692,51693,51694,51695,51696,51697,51698,51699,51700,51701,51702,51703,51704,51705,51706,51707,51708,51709,51710,51711,51712,51713,51714,51715,51716,51717,51718,51719,51720,51721,51722,51723,51724,51725,51726,51727,51728,51729,51730,51731,51732,51733,51734,51735,51736,51737,51738,51739,51740,51741,51742,51743,51744,51745,51746,51747,51748,51749,51750,51751,51752,51753,51754,51755,51756,51757,51758,51759,51760,51761,51762,51763,51764,51765,51766,51767,51768,51769,51770,51771,51772,51773,51774,51775,51776,51777,51778,51779,51780,51781,51782,51783,51784,51785,51786,51787,51788,51789,51790,51791,51792,51793,51794,51795,51796,51797,51798,51799,51800,51801,51802,51803,51804,51805,51806,51807,51808,51809,51810,51811,51812,51813,51814,51815,51816,51817,51818,51819,51820,51821,51822,51823,51824,51825,51826,51827,51828,51829,51830,51831,51832,51833,51834,51835,51836,51837,51838,51839,51840,51841,51842,51843,51844,51845,51846,51847,51848,51849,51850,51851,51852,51853,51854,51855,51856,51857,51858,51859,51860,51861,51862,51863,51864,51865,51866,51867,51868,51869,51870,51871,51872,51873,51874,51875,51876,51877,51878,51879,51880,51881,51882,51883,51884,51885,51886,51887,51888,51889,51890,51891,51892,51893,51894,51895,51896,51897,51898,51899,51900,51901,51902,51903,51904,51905,51906,51907,51908,51909,51910,51911,51912,51913,51914,51915,51916,51917,51918,51919,51920,51921,51922,51923,51924,51925,51926,51927,51928,51929,51930,51931,51932,51933,51934,51935,51936,51937,51938,51939,51940,51941,51942,51943,51944,51945,51946,51947,51948,51949,51950,51951,51952,51953,51954,51955,51956,51957,51958,51959,51960,51961,51962,51963,51964,51965,51966,51967,51968,51969,51970,51971,51972,51973,51974,51975,51976,51977,51978,51979,51980,51981,51982,51983,51984,51985,51986,51987,51988,51989,51990,51991,51992,51993,51994,51995,51996,51997,51998,51999,52000,52001,52002,52003,52004,52005,52006,52007,52008,52009,52010,52011,52012,52013,52014,52015,52016,52017,52018,52019,52020,52021,52022,52023,52024,52025,52026,52027,52028,52029,52030,52031,52032,52033,52034,52035,52036,52037,52038,52039,52040,52041,52042,52043,52044,52045,52046,52047,52048,52049,52050,52051,52052,52053,52054,52055,52056,52057,52058,52059,52060,52061,52062,52063,52064,52065,52066,52067,52068,52069,52070,52071,52072,52073,52074,52075,52076,52077,52078,52079,52080,52081,52082,52083,52084,52085,52086,52087,52088,52089,52090,52091,52092,52093,52094,52095,52096,52097,52098,52099,52100,52101,52102,52103,52104,52105,52106,52107,52108,52109,52110,52111,52112,52113,52114,52115,52116,52117,52118,52119,52120,52121,52122,52123,52124,52125,52126,52127,52128,52129,52130,52131,52132,52133,52134,52135,52136,52137,52138,52139,52140,52141,52142,52143,52144,52145,52146,52147,52148,52149,52150,52151,52152,52153,52154,52155,52156,52157,52158,52159,52160,52161,52162,52163,52164,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174,52175,52176,52177,52178,52179,52180,52181,52182,52183,52184,52185,52186,52187,52188,52189,52190,52191,52192,52193,52194,52195,52196,52197,52198,52199,52200,52201,52202,52203,52204,52205,52206,52207,52208,52209,52210,52211,52212,52213,52214,52215,52216,52217,52218,52219,52220,52221,52222,52223,52224,52225,52226,52227,52228,52229,52230,52231,52232,52233,52234,52235,52236,52237,52238,52239,52240,52241,52242,52243,52244,52245,52246,52247,52248,52249,52250,52251,52252,52253,52254,52255,52256,52257,52258,52259,52260,52261,52262,52263,52264,52265,52266,52267,52268,52269,52270,52271,52272,52273,52274,52275,52276,52277,52278,52279,52280,52281,52282,52283,52284,52285,52286,52287,52288,52289,52290,52291,52292,52293,52294,52295,52296,52297,52298,52299,52300,52301,52302,52303,52304,52305,52306,52307,52308,52309,52310,52311,52312,52313,52314,52315,52316,52317,52318,52319,52320,52321,52322,52323,52324,52325,52326,52327,52328,52329,52330,52331,52332,52333,52334,52335,52336,52337,52338,52339,52340,52341,52342,52343,52344,52345,52346,52347,52348,52349,52350,52351,52352,52353,52354,52355,52356,52357,52358,52359,52360,52361,52362,52363,52364,52365,52366,52367,52368,52369,52370,52371,52372,52373,52374,52375,52376,52377,52378,52379,52380,52381,52382,52383,52384,52385,52386,52387,52388,52389,52390,52391,52392,52393,52394,52395,52396,52397,52398,52399,52400,52401,52402,52403,52404,52405,52406,52407,52408,52409,52410,52411,52412,52413,52414,52415,52416,52417,52418,52419,52420,52421,52422,52423,52424,52425,52426,52427,52428,52429,52430,52431,52432,52433,52434,52435,52436,52437,52438,52439,52440,52441,52442,52443,52444,52445,52446,52447,52448,52449,52450,52451,52452,52453,52454,52455,52456,52457,52458,52459,52460,52461,52462,52463,52464,52465,52466,52467,52468,52469,52470,52471,52472,52473,52474,52475,52476,52477,52478,52479,52480,52481,52482,52483,52484,52485,52486,52487,52488,52489,52490,52491,52492,52493,52494,52495,52496,52497,52498,52499,52500,52501,52502,52503,52504,52505,52506,52507,52508,52509,52510,52511,52512,52513,52514,52515,52516,52517,52518,52519,52520,52521,52522,52523,52524,52525,52526,52527,52528,52529,52530,52531,52532,52533,52534,52535,52536,52537,52538,52539,52540,52541,52542,52543,52544,52545,52546,52547,52548,52549,52550,52551,52552,52553,52554,52555,52556,52557,52558,52559,52560,52561,52562,52563,52564,52565,52566,52567,52568,52569,52570,52571,52572,52573,52574,52575,52576,52577,52578,52579,52580,52581,52582,52583,52584,52585,52586,52587,52588,52589,52590,52591,52592,52593,52594,52595,52596,52597,52598,52599,52600,52601,52602,52603,52604,52605,52606,52607,52608,52609,52610,52611,52612,52613,52614,52615,52616,52617,52618,52619,52620,52621,52622,52623,52624,52625,52626,52627,52628,52629,52630,52631,52632,52633,52634,52635,52636,52637,52638,52639,52640,52641,52642,52643,52644,52645,52646,52647,52648,52649,52650,52651,52652,52653,52654,52655,52656,52657,52658,52659,52660,52661,52662,52663,52664,52665,52666,52667,52668,52669,52670,52671,52672,52673,52674,52675,52676,52677,52678,52679,52680,52681,52682,52683,52684,52685,52686,52687,52688,52689,52690,52691,52692,52693,52694,52695,52696,52697,52698,52699,52700,52701,52702,52703,52704,52705,52706,52707,52708,52709,52710,52711,52712,52713,52714,52715,52716,52717,52718,52719,52720,52721,52722,52723,52724,52725,52726,52727,52728,52729,52730,52731,52732,52733,52734,52735,52736,52737,52738,52739,52740,52741,52742,52743,52744,52745,52746,52747,52748,52749,52750,52751,52752,52753,52754,52755,52756,52757,52758,52759,52760,52761,52762,52763,52764,52765,52766,52767,52768,52769,52770,52771,52772,52773,52774,52775,52776,52777,52778,52779,52780,52781,52782,52783,52784,52785,52786,52787,52788,52789,52790,52791,52792,52793,52794,52795,52796,52797,52798,52799,52800,52801,52802,52803,52804,52805,52806,52807,52808,52809,52810,52811,52812,52813,52814,52815,52816,52817,52818,52819,52820,52821,52822,52823,52824,52825,52826,52827,52828,52829,52830,52831,52832,52833,52834,52835,52836,52837,52838,52839,52840,52841,52842,52843,52844,52845,52846,52847,52848,52849,52850,52851,52852,52853,52854,52855,52856,52857,52858,52859,52860,52861,52862,52863,52864,52865,52866,52867,52868,52869,52870,52871,52872,52873,52874,52875,52876,52877,52878,52879,52880,52881,52882,52883,52884,52885,52886,52887,52888,52889,52890,52891,52892,52893,52894,52895,52896,52897,52898,52899,52900,52901,52902,52903,52904,52905,52906,52907,52908,52909,52910,52911,52912,52913,52914,52915,52916,52917,52918,52919,52920,52921,52922,52923,52924,52925,52926,52927,52928,52929,52930,52931,52932,52933,52934,52935,52936,52937,52938,52939,52940,52941,52942,52943,52944,52945,52946,52947,52948,52949,52950,52951,52952,52953,52954,52955,52956,52957,52958,52959,52960,52961,52962,52963,52964,52965,52966,52967,52968,52969,52970,52971,52972,52973,52974,52975,52976,52977,52978,52979,52980,52981,52982,52983,52984,52985,52986,52987,52988,52989,52990,52991,52992,52993,52994,52995,52996,52997,52998,52999,53000,53001,53002,53003,53004,53005,53006,53007,53008,53009,53010,53011,53012,53013,53014,53015,53016,53017,53018,53019,53020,53021,53022,53023,53024,53025,53026,53027,53028,53029,53030,53031,53032,53033,53034,53035,53036,53037,53038,53039,53040,53041,53042,53043,53044,53045,53046,53047,53048,53049,53050,53051,53052,53053,53054,53055,53056,53057,53058,53059,53060,53061,53062,53063,53064,53065,53066,53067,53068,53069,53070,53071,53072,53073,53074,53075,53076,53077,53078,53079,53080,53081,53082,53083,53084,53085,53086,53087,53088,53089,53090,53091,53092,53093,53094,53095,53096,53097,53098,53099,53100,53101,53102,53103,53104,53105,53106,53107,53108,53109,53110,53111,53112,53113,53114,53115,53116,53117,53118,53119,53120,53121,53122,53123,53124,53125,53126,53127,53128,53129,53130,53131,53132,53133,53134,53135,53136,53137,53138,53139,53140,53141,53142,53143,53144,53145,53146,53147,53148,53149,53150,53151,53152,53153,53154,53155,53156,53157,53158,53159,53160,53161,53162,53163,53164,53165,53166,53167,53168,53169,53170,53171,53172,53173,53174,53175,53176,53177,53178,53179,53180,53181,53182,53183,53184,53185,53186,53187,53188,53189,53190,53191,53192,53193,53194,53195,53196,53197,53198,53199,53200,53201,53202,53203,53204,53205,53206,53207,53208,53209,53210,53211,53212,53213,53214,53215,53216,53217,53218,53219,53220,53221,53222,53223,53224,53225,53226,53227,53228,53229,53230,53231,53232,53233,53234,53235,53236,53237,53238,53239,53240,53241,53242,53243,53244,53245,53246,53247,53248,53249,53250,53251,53252,53253,53254,53255,53256,53257,53258,53259,53260,53261,53262,53263,53264,53265,53266,53267,53268,53269,53270,53271,53272,53273,53274,53275,53276,53277,53278,53279,53280,53281,53282,53283,53284,53285,53286,53287,53288,53289,53290,53291,53292,53293,53294,53295,53296,53297,53298,53299,53300,53301,53302,53303,53304,53305,53306,53307,53308,53309,53310,53311,53312,53313,53314,53315,53316,53317,53318,53319,53320,53321,53322,53323,53324,53325,53326,53327,53328,53329,53330,53331,53332,53333,53334,53335,53336,53337,53338,53339,53340,53341,53342,53343,53344,53345,53346,53347,53348,53349,53350,53351,53352,53353,53354,53355,53356,53357,53358,53359,53360,53361,53362,53363,53364,53365,53366,53367,53368,53369,53370,53371,53372,53373,53374,53375,53376,53377,53378,53379,53380,53381,53382,53383,53384,53385,53386,53387,53388,53389,53390,53391,53392,53393,53394,53395,53396,53397,53398,53399,53400,53401,53402,53403,53404,53405,53406,53407,53408,53409,53410,53411,53412,53413,53414,53415,53416,53417,53418,53419,53420,53421,53422,53423,53424,53425,53426,53427,53428,53429,53430,53431,53432,53433,53434,53435,53436,53437,53438,53439,53440,53441,53442,53443,53444,53445,53446,53447,53448,53449,53450,53451,53452,53453,53454,53455,53456,53457,53458,53459,53460,53461,53462,53463,53464,53465,53466,53467,53468,53469,53470,53471,53472,53473,53474,53475,53476,53477,53478,53479,53480,53481,53482,53483,53484,53485,53486,53487,53488,53489,53490,53491,53492,53493,53494,53495,53496,53497,53498,53499,53500,53501,53502,53503,53504,53505,53506,53507,53508,53509,53510,53511,53512,53513,53514,53515,53516,53517,53518,53519,53520,53521,53522,53523,53524,53525,53526,53527,53528,53529,53530,53531,53532,53533,53534,53535,53536,53537,53538,53539,53540,53541,53542,53543,53544,53545,53546,53547,53548,53549,53550,53551,53552,53553,53554,53555,53556,53557,53558,53559,53560,53561,53562,53563,53564,53565,53566,53567,53568,53569,53570,53571,53572,53573,53574,53575,53576,53577,53578,53579,53580,53581,53582,53583,53584,53585,53586,53587,53588,53589,53590,53591,53592,53593,53594,53595,53596,53597,53598,53599,53600,53601,53602,53603,53604,53605,53606,53607,53608,53609,53610,53611,53612,53613,53614,53615,53616,53617,53618,53619,53620,53621,53622,53623,53624,53625,53626,53627,53628,53629,53630,53631,53632,53633,53634,53635,53636,53637,53638,53639,53640,53641,53642,53643,53644,53645,53646,53647,53648,53649,53650,53651,53652,53653,53654,53655,53656,53657,53658,53659,53660,53661,53662,53663,53664,53665,53666,53667,53668,53669,53670,53671,53672,53673,53674,53675,53676,53677,53678,53679,53680,53681,53682,53683,53684,53685,53686,53687,53688,53689,53690,53691,53692,53693,53694,53695,53696,53697,53698,53699,53700,53701,53702,53703,53704,53705,53706,53707,53708,53709,53710,53711,53712,53713,53714,53715,53716,53717,53718,53719,53720,53721,53722,53723,53724,53725,53726,53727,53728,53729,53730,53731,53732,53733,53734,53735,53736,53737,53738,53739,53740,53741,53742,53743,53744,53745,53746,53747,53748,53749,53750,53751,53752,53753,53754,53755,53756,53757,53758,53759,53760,53761,53762,53763,53764,53765,53766,53767,53768,53769,53770,53771,53772,53773,53774,53775,53776,53777,53778,53779,53780,53781,53782,53783,53784,53785,53786,53787,53788,53789,53790,53791,53792,53793,53794,53795,53796,53797,53798,53799,53800,53801,53802,53803,53804,53805,53806,53807,53808,53809,53810,53811,53812,53813,53814,53815,53816,53817,53818,53819,53820,53821,53822,53823,53824,53825,53826,53827,53828,53829,53830,53831,53832,53833,53834,53835,53836,53837,53838,53839,53840,53841,53842,53843,53844,53845,53846,53847,53848,53849,53850,53851,53852,53853,53854,53855,53856,53857,53858,53859,53860,53861,53862,53863,53864,53865,53866,53867,53868,53869,53870,53871,53872,53873,53874,53875,53876,53877,53878,53879,53880,53881,53882,53883,53884,53885,53886,53887,53888,53889,53890,53891,53892,53893,53894,53895,53896,53897,53898,53899,53900,53901,53902,53903,53904,53905,53906,53907,53908,53909,53910,53911,53912,53913,53914,53915,53916,53917,53918,53919,53920,53921,53922,53923,53924,53925,53926,53927,53928,53929,53930,53931,53932,53933,53934,53935,53936,53937,53938,53939,53940,53941,53942,53943,53944,53945,53946,53947,53948,53949,53950,53951,53952,53953,53954,53955,53956,53957,53958,53959,53960,53961,53962,53963,53964,53965,53966,53967,53968,53969,53970,53971,53972,53973,53974,53975,53976,53977,53978,53979,53980,53981,53982,53983,53984,53985,53986,53987,53988,53989,53990,53991,53992,53993,53994,53995,53996,53997,53998,53999,54000,54001,54002,54003,54004,54005,54006,54007,54008,54009,54010,54011,54012,54013,54014,54015,54016,54017,54018,54019,54020,54021,54022,54023,54024,54025,54026,54027,54028,54029,54030,54031,54032,54033,54034,54035,54036,54037,54038,54039,54040,54041,54042,54043,54044,54045,54046,54047,54048,54049,54050,54051,54052,54053,54054,54055,54056,54057,54058,54059,54060,54061,54062,54063,54064,54065,54066,54067,54068,54069,54070,54071,54072,54073,54074,54075,54076,54077,54078,54079,54080,54081,54082,54083,54084,54085,54086,54087,54088,54089,54090,54091,54092,54093,54094,54095,54096,54097,54098,54099,54100,54101,54102,54103,54104,54105,54106,54107,54108,54109,54110,54111,54112,54113,54114,54115,54116,54117,54118,54119,54120,54121,54122,54123,54124,54125,54126,54127,54128,54129,54130,54131,54132,54133,54134,54135,54136,54137,54138,54139,54140,54141,54142,54143,54144,54145,54146,54147,54148,54149,54150,54151,54152,54153,54154,54155,54156,54157,54158,54159,54160,54161,54162,54163,54164,54165,54166,54167,54168,54169,54170,54171,54172,54173,54174,54175,54176,54177,54178,54179,54180,54181,54182,54183,54184,54185,54186,54187,54188,54189,54190,54191,54192,54193,54194,54195,54196,54197,54198,54199,54200,54201,54202,54203,54204,54205,54206,54207,54208,54209,54210,54211,54212,54213,54214,54215,54216,54217,54218,54219,54220,54221,54222,54223,54224,54225,54226,54227,54228,54229,54230,54231,54232,54233,54234,54235,54236,54237,54238,54239,54240,54241,54242,54243,54244,54245,54246,54247,54248,54249,54250,54251,54252,54253,54254,54255,54256,54257,54258,54259,54260,54261,54262,54263,54264,54265,54266,54267,54268,54269,54270,54271,54272,54273,54274,54275,54276,54277,54278,54279,54280,54281,54282,54283,54284,54285,54286,54287,54288,54289,54290,54291,54292,54293,54294,54295,54296,54297,54298,54299,54300,54301,54302,54303,54304,54305,54306,54307,54308,54309,54310,54311,54312,54313,54314,54315,54316,54317,54318,54319,54320,54321,54322,54323,54324,54325,54326,54327,54328,54329,54330,54331,54332,54333,54334,54335,54336,54337,54338,54339,54340,54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,54352,54353,54354,54355,54356,54357,54358,54359,54360,54361,54362,54363,54364,54365,54366,54367,54368,54369,54370,54371,54372,54373,54374,54375,54376,54377,54378,54379,54380,54381,54382,54383,54384,54385,54386,54387,54388,54389,54390,54391,54392,54393,54394,54395,54396,54397,54398,54399,54400,54401,54402,54403,54404,54405,54406,54407,54408,54409,54410,54411,54412,54413,54414,54415,54416,54417,54418,54419,54420,54421,54422,54423,54424,54425,54426,54427,54428,54429,54430,54431,54432,54433,54434,54435,54436,54437,54438,54439,54440,54441,54442,54443,54444,54445,54446,54447,54448,54449,54450,54451,54452,54453,54454,54455,54456,54457,54458,54459,54460,54461,54462,54463,54464,54465,54466,54467,54468,54469,54470,54471,54472,54473,54474,54475,54476,54477,54478,54479,54480,54481,54482,54483,54484,54485,54486,54487,54488,54489,54490,54491,54492,54493,54494,54495,54496,54497,54498,54499,54500,54501,54502,54503,54504,54505,54506,54507,54508,54509,54510,54511,54512,54513,54514,54515,54516,54517,54518,54519,54520,54521,54522,54523,54524,54525,54526,54527,54528,54529,54530,54531,54532,54533,54534,54535,54536,54537,54538,54539,54540,54541,54542,54543,54544,54545,54546,54547,54548,54549,54550,54551,54552,54553,54554,54555,54556,54557,54558,54559,54560,54561,54562,54563,54564,54565,54566,54567,54568,54569,54570,54571,54572,54573,54574,54575,54576,54577,54578,54579,54580,54581,54582,54583,54584,54585,54586,54587,54588,54589,54590,54591,54592,54593,54594,54595,54596,54597,54598,54599,54600,54601,54602,54603,54604,54605,54606,54607,54608,54609,54610,54611,54612,54613,54614,54615,54616,54617,54618,54619,54620,54621,54622,54623,54624,54625,54626,54627,54628,54629,54630,54631,54632,54633,54634,54635,54636,54637,54638,54639,54640,54641,54642,54643,54644,54645,54646,54647,54648,54649,54650,54651,54652,54653,54654,54655,54656,54657,54658,54659,54660,54661,54662,54663,54664,54665,54666,54667,54668,54669,54670,54671,54672,54673,54674,54675,54676,54677,54678,54679,54680,54681,54682,54683,54684,54685,54686,54687,54688,54689,54690,54691,54692,54693,54694,54695,54696,54697,54698,54699,54700,54701,54702,54703,54704,54705,54706,54707,54708,54709,54710,54711,54712,54713,54714,54715,54716,54717,54718,54719,54720,54721,54722,54723,54724,54725,54726,54727,54728,54729,54730,54731,54732,54733,54734,54735,54736,54737,54738,54739,54740,54741,54742,54743,54744,54745,54746,54747,54748,54749,54750,54751,54752,54753,54754,54755,54756,54757,54758,54759,54760,54761,54762,54763,54764,54765,54766,54767,54768,54769,54770,54771,54772,54773,54774,54775,54776,54777,54778,54779,54780,54781,54782,54783,54784,54785,54786,54787,54788,54789,54790,54791,54792,54793,54794,54795,54796,54797,54798,54799,54800,54801,54802,54803,54804,54805,54806,54807,54808,54809,54810,54811,54812,54813,54814,54815,54816,54817,54818,54819,54820,54821,54822,54823,54824,54825,54826,54827,54828,54829,54830,54831,54832,54833,54834,54835,54836,54837,54838,54839,54840,54841,54842,54843,54844,54845,54846,54847,54848,54849,54850,54851,54852,54853,54854,54855,54856,54857,54858,54859,54860,54861,54862,54863,54864,54865,54866,54867,54868,54869,54870,54871,54872,54873,54874,54875,54876,54877,54878,54879,54880,54881,54882,54883,54884,54885,54886,54887,54888,54889,54890,54891,54892,54893,54894,54895,54896,54897,54898,54899,54900,54901,54902,54903,54904,54905,54906,54907,54908,54909,54910,54911,54912,54913,54914,54915,54916,54917,54918,54919,54920,54921,54922,54923,54924,54925,54926,54927,54928,54929,54930,54931,54932,54933,54934,54935,54936,54937,54938,54939,54940,54941,54942,54943,54944,54945,54946,54947,54948,54949,54950,54951,54952,54953,54954,54955,54956,54957,54958,54959,54960,54961,54962,54963,54964,54965,54966,54967,54968,54969,54970,54971,54972,54973,54974,54975,54976,54977,54978,54979,54980,54981,54982,54983,54984,54985,54986,54987,54988,54989,54990,54991,54992,54993,54994,54995,54996,54997,54998,54999,55000,55001,55002,55003,55004,55005,55006,55007,55008,55009,55010,55011,55012,55013,55014,55015,55016,55017,55018,55019,55020,55021,55022,55023,55024,55025,55026,55027,55028,55029,55030,55031,55032,55033,55034,55035,55036,55037,55038,55039,55040,55041,55042,55043,55044,55045,55046,55047,55048,55049,55050,55051,55052,55053,55054,55055,55056,55057,55058,55059,55060,55061,55062,55063,55064,55065,55066,55067,55068,55069,55070,55071,55072,55073,55074,55075,55076,55077,55078,55079,55080,55081,55082,55083,55084,55085,55086,55087,55088,55089,55090,55091,55092,55093,55094,55095,55096,55097,55098,55099,55100,55101,55102,55103,55104,55105,55106,55107,55108,55109,55110,55111,55112,55113,55114,55115,55116,55117,55118,55119,55120,55121,55122,55123,55124,55125,55126,55127,55128,55129,55130,55131,55132,55133,55134,55135,55136,55137,55138,55139,55140,55141,55142,55143,55144,55145,55146,55147,55148,55149,55150,55151,55152,55153,55154,55155,55156,55157,55158,55159,55160,55161,55162,55163,55164,55165,55166,55167,55168,55169,55170,55171,55172,55173,55174,55175,55176,55177,55178,55179,55180,55181,55182,55183,55184,55185,55186,55187,55188,55189,55190,55191,55192,55193,55194,55195,55196,55197,55198,55199,55200,55201,55202,55203,55216,55217,55218,55219,55220,55221,55222,55223,55224,55225,55226,55227,55228,55229,55230,55231,55232,55233,55234,55235,55236,55237,55238,55243,55244,55245,55246,55247,55248,55249,55250,55251,55252,55253,55254,55255,55256,55257,55258,55259,55260,55261,55262,55263,55264,55265,55266,55267,55268,55269,55270,55271,55272,55273,55274,55275,55276,55277,55278,55279,55280,55281,55282,55283,55284,55285,55286,55287,55288,55289,55290,55291,63744,63745,63746,63747,63748,63749,63750,63751,63752,63753,63754,63755,63756,63757,63758,63759,63760,63761,63762,63763,63764,63765,63766,63767,63768,63769,63770,63771,63772,63773,63774,63775,63776,63777,63778,63779,63780,63781,63782,63783,63784,63785,63786,63787,63788,63789,63790,63791,63792,63793,63794,63795,63796,63797,63798,63799,63800,63801,63802,63803,63804,63805,63806,63807,63808,63809,63810,63811,63812,63813,63814,63815,63816,63817,63818,63819,63820,63821,63822,63823,63824,63825,63826,63827,63828,63829,63830,63831,63832,63833,63834,63835,63836,63837,63838,63839,63840,63841,63842,63843,63844,63845,63846,63847,63848,63849,63850,63851,63852,63853,63854,63855,63856,63857,63858,63859,63860,63861,63862,63863,63864,63865,63866,63867,63868,63869,63870,63871,63872,63873,63874,63875,63876,63877,63878,63879,63880,63881,63882,63883,63884,63885,63886,63887,63888,63889,63890,63891,63892,63893,63894,63895,63896,63897,63898,63899,63900,63901,63902,63903,63904,63905,63906,63907,63908,63909,63910,63911,63912,63913,63914,63915,63916,63917,63918,63919,63920,63921,63922,63923,63924,63925,63926,63927,63928,63929,63930,63931,63932,63933,63934,63935,63936,63937,63938,63939,63940,63941,63942,63943,63944,63945,63946,63947,63948,63949,63950,63951,63952,63953,63954,63955,63956,63957,63958,63959,63960,63961,63962,63963,63964,63965,63966,63967,63968,63969,63970,63971,63972,63973,63974,63975,63976,63977,63978,63979,63980,63981,63982,63983,63984,63985,63986,63987,63988,63989,63990,63991,63992,63993,63994,63995,63996,63997,63998,63999,64000,64001,64002,64003,64004,64005,64006,64007,64008,64009,64010,64011,64012,64013,64014,64015,64016,64017,64018,64019,64020,64021,64022,64023,64024,64025,64026,64027,64028,64029,64030,64031,64032,64033,64034,64035,64036,64037,64038,64039,64040,64041,64042,64043,64044,64045,64046,64047,64048,64049,64050,64051,64052,64053,64054,64055,64056,64057,64058,64059,64060,64061,64062,64063,64064,64065,64066,64067,64068,64069,64070,64071,64072,64073,64074,64075,64076,64077,64078,64079,64080,64081,64082,64083,64084,64085,64086,64087,64088,64089,64090,64091,64092,64093,64094,64095,64096,64097,64098,64099,64100,64101,64102,64103,64104,64105,64106,64107,64108,64109,64112,64113,64114,64115,64116,64117,64118,64119,64120,64121,64122,64123,64124,64125,64126,64127,64128,64129,64130,64131,64132,64133,64134,64135,64136,64137,64138,64139,64140,64141,64142,64143,64144,64145,64146,64147,64148,64149,64150,64151,64152,64153,64154,64155,64156,64157,64158,64159,64160,64161,64162,64163,64164,64165,64166,64167,64168,64169,64170,64171,64172,64173,64174,64175,64176,64177,64178,64179,64180,64181,64182,64183,64184,64185,64186,64187,64188,64189,64190,64191,64192,64193,64194,64195,64196,64197,64198,64199,64200,64201,64202,64203,64204,64205,64206,64207,64208,64209,64210,64211,64212,64213,64214,64215,64216,64217,64256,64257,64258,64259,64260,64261,64262,64275,64276,64277,64278,64279,64285,64287,64288,64289,64290,64291,64292,64293,64294,64295,64296,64298,64299,64300,64301,64302,64303,64304,64305,64306,64307,64308,64309,64310,64312,64313,64314,64315,64316,64318,64320,64321,64323,64324,64326,64327,64328,64329,64330,64331,64332,64333,64334,64335,64336,64337,64338,64339,64340,64341,64342,64343,64344,64345,64346,64347,64348,64349,64350,64351,64352,64353,64354,64355,64356,64357,64358,64359,64360,64361,64362,64363,64364,64365,64366,64367,64368,64369,64370,64371,64372,64373,64374,64375,64376,64377,64378,64379,64380,64381,64382,64383,64384,64385,64386,64387,64388,64389,64390,64391,64392,64393,64394,64395,64396,64397,64398,64399,64400,64401,64402,64403,64404,64405,64406,64407,64408,64409,64410,64411,64412,64413,64414,64415,64416,64417,64418,64419,64420,64421,64422,64423,64424,64425,64426,64427,64428,64429,64430,64431,64432,64433,64467,64468,64469,64470,64471,64472,64473,64474,64475,64476,64477,64478,64479,64480,64481,64482,64483,64484,64485,64486,64487,64488,64489,64490,64491,64492,64493,64494,64495,64496,64497,64498,64499,64500,64501,64502,64503,64504,64505,64506,64507,64508,64509,64510,64511,64512,64513,64514,64515,64516,64517,64518,64519,64520,64521,64522,64523,64524,64525,64526,64527,64528,64529,64530,64531,64532,64533,64534,64535,64536,64537,64538,64539,64540,64541,64542,64543,64544,64545,64546,64547,64548,64549,64550,64551,64552,64553,64554,64555,64556,64557,64558,64559,64560,64561,64562,64563,64564,64565,64566,64567,64568,64569,64570,64571,64572,64573,64574,64575,64576,64577,64578,64579,64580,64581,64582,64583,64584,64585,64586,64587,64588,64589,64590,64591,64592,64593,64594,64595,64596,64597,64598,64599,64600,64601,64602,64603,64604,64605,64606,64607,64608,64609,64610,64611,64612,64613,64614,64615,64616,64617,64618,64619,64620,64621,64622,64623,64624,64625,64626,64627,64628,64629,64630,64631,64632,64633,64634,64635,64636,64637,64638,64639,64640,64641,64642,64643,64644,64645,64646,64647,64648,64649,64650,64651,64652,64653,64654,64655,64656,64657,64658,64659,64660,64661,64662,64663,64664,64665,64666,64667,64668,64669,64670,64671,64672,64673,64674,64675,64676,64677,64678,64679,64680,64681,64682,64683,64684,64685,64686,64687,64688,64689,64690,64691,64692,64693,64694,64695,64696,64697,64698,64699,64700,64701,64702,64703,64704,64705,64706,64707,64708,64709,64710,64711,64712,64713,64714,64715,64716,64717,64718,64719,64720,64721,64722,64723,64724,64725,64726,64727,64728,64729,64730,64731,64732,64733,64734,64735,64736,64737,64738,64739,64740,64741,64742,64743,64744,64745,64746,64747,64748,64749,64750,64751,64752,64753,64754,64755,64756,64757,64758,64759,64760,64761,64762,64763,64764,64765,64766,64767,64768,64769,64770,64771,64772,64773,64774,64775,64776,64777,64778,64779,64780,64781,64782,64783,64784,64785,64786,64787,64788,64789,64790,64791,64792,64793,64794,64795,64796,64797,64798,64799,64800,64801,64802,64803,64804,64805,64806,64807,64808,64809,64810,64811,64812,64813,64814,64815,64816,64817,64818,64819,64820,64821,64822,64823,64824,64825,64826,64827,64828,64829,64848,64849,64850,64851,64852,64853,64854,64855,64856,64857,64858,64859,64860,64861,64862,64863,64864,64865,64866,64867,64868,64869,64870,64871,64872,64873,64874,64875,64876,64877,64878,64879,64880,64881,64882,64883,64884,64885,64886,64887,64888,64889,64890,64891,64892,64893,64894,64895,64896,64897,64898,64899,64900,64901,64902,64903,64904,64905,64906,64907,64908,64909,64910,64911,64914,64915,64916,64917,64918,64919,64920,64921,64922,64923,64924,64925,64926,64927,64928,64929,64930,64931,64932,64933,64934,64935,64936,64937,64938,64939,64940,64941,64942,64943,64944,64945,64946,64947,64948,64949,64950,64951,64952,64953,64954,64955,64956,64957,64958,64959,64960,64961,64962,64963,64964,64965,64966,64967,65008,65009,65010,65011,65012,65013,65014,65015,65016,65017,65018,65019,65136,65137,65138,65139,65140,65142,65143,65144,65145,65146,65147,65148,65149,65150,65151,65152,65153,65154,65155,65156,65157,65158,65159,65160,65161,65162,65163,65164,65165,65166,65167,65168,65169,65170,65171,65172,65173,65174,65175,65176,65177,65178,65179,65180,65181,65182,65183,65184,65185,65186,65187,65188,65189,65190,65191,65192,65193,65194,65195,65196,65197,65198,65199,65200,65201,65202,65203,65204,65205,65206,65207,65208,65209,65210,65211,65212,65213,65214,65215,65216,65217,65218,65219,65220,65221,65222,65223,65224,65225,65226,65227,65228,65229,65230,65231,65232,65233,65234,65235,65236,65237,65238,65239,65240,65241,65242,65243,65244,65245,65246,65247,65248,65249,65250,65251,65252,65253,65254,65255,65256,65257,65258,65259,65260,65261,65262,65263,65264,65265,65266,65267,65268,65269,65270,65271,65272,65273,65274,65275,65276,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65382,65383,65384,65385,65386,65387,65388,65389,65390,65391,65392,65393,65394,65395,65396,65397,65398,65399,65400,65401,65402,65403,65404,65405,65406,65407,65408,65409,65410,65411,65412,65413,65414,65415,65416,65417,65418,65419,65420,65421,65422,65423,65424,65425,65426,65427,65428,65429,65430,65431,65432,65433,65434,65435,65436,65437,65438,65439,65440,65441,65442,65443,65444,65445,65446,65447,65448,65449,65450,65451,65452,65453,65454,65455,65456,65457,65458,65459,65460,65461,65462,65463,65464,65465,65466,65467,65468,65469,65470,65474,65475,65476,65477,65478,65479,65482,65483,65484,65485,65486,65487,65490,65491,65492,65493,65494,65495,65498,65499,65500'; +var arr = str.split(',').map(function(code) { + return parseInt(code, 10); +}); +module.exports = arr; +},{}],"/../../../jshint/node_modules/console-browserify/index.js":[function(_dereq_,module,exports){ +(function (global){ +/*global window, global*/ +var util = _dereq_("util") +var assert = _dereq_("assert") +var now = _dereq_("date-now") + +var slice = Array.prototype.slice +var console +var times = {} + +if (typeof global !== "undefined" && global.console) { + console = global.console +} else if (typeof window !== "undefined" && window.console) { + console = window.console +} else { + console = {} +} - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } - throw TypeError('Uncaught, unspecified "error" event.'); +var functions = [ + [log, "log"], + [info, "info"], + [warn, "warn"], + [error, "error"], + [time, "time"], + [timeEnd, "timeEnd"], + [trace, "trace"], + [dir, "dir"], + [consoleAssert, "assert"] +] + +for (var i = 0; i < functions.length; i++) { + var tuple = functions[i] + var f = tuple[0] + var name = tuple[1] + + if (!console[name]) { + console[name] = f } - } +} - handler = this._events[type]; +module.exports = console - if (isUndefined(handler)) - return false; +function log() {} - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - handler.apply(this, args); - } - } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; +function info() { + console.log.apply(console, arguments) +} - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } +function warn() { + console.log.apply(console, arguments) +} - return true; -}; +function error() { + console.warn.apply(console, arguments) +} -EventEmitter.prototype.addListener = function(type, listener) { - var m; +function time(label) { + times[label] = now() +} - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +function timeEnd(label) { + var time = times[label] + if (!time) { + throw new Error("No such label: " + label) + } - if (!this._events) - this._events = {}; + var duration = now() - time + console.log(label + ": " + duration + "ms") +} - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); +function trace() { + var err = new Error() + err.name = "Trace" + err.message = util.format.apply(null, arguments) + console.error(err.stack) +} - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; +function dir(object) { + console.log(util.inspect(object) + "\n") +} - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - var m; - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; +function consoleAssert(expression) { + if (!expression) { + var arr = slice.call(arguments, 1) + assert.ok(false, util.format.apply(null, arr)) } +} - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"assert":"/node_modules/assert/assert.js","date-now":"/../../../jshint/node_modules/date-now/index.js","util":"/node_modules/util/util.js"}],"/../../../jshint/node_modules/date-now/index.js":[function(_dereq_,module,exports){ +module.exports = now - return this; -}; +function now() { + return new Date().getTime() +} -EventEmitter.prototype.on = EventEmitter.prototype.addListener; +},{}],"/../../../jshint/node_modules/lodash.clone/index.js":[function(_dereq_,module,exports){ +(function (global){ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; - var fired = false; +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - function g() { - this.removeListener(type, g); +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; - g.listener = listener; - this.on(type, g); +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; - return this; -}; +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = +cloneableTags[boolTag] = cloneableTags[dateTag] = +cloneableTags[float32Tag] = cloneableTags[float64Tag] = +cloneableTags[int8Tag] = cloneableTags[int16Tag] = +cloneableTags[int32Tag] = cloneableTags[mapTag] = +cloneableTags[numberTag] = cloneableTags[objectTag] = +cloneableTags[regexpTag] = cloneableTags[setTag] = +cloneableTags[stringTag] = cloneableTags[symbolTag] = +cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = +cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - if (!this._events || !this._events[type]) - return this; +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); - list = this._events[type]; - length = list.length; - position = -1; +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; - if (position < 0) - return this; +/** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ +function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; +} - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } +/** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ +function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; +} - if (this._events.removeListener) - this.emit('removeListener', type, listener); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } } + return array; +} - return this; -}; +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} - if (!this._events) - return this; +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); } + return accumulator; +} - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } - - listeners = this._events[type]; +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); + while (++index < n) { + result[index] = iteratee(index); } - delete this._events[type]; - - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; - -EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; -}; - -function isFunction(arg) { - return typeof arg === 'function'; + return result; } -function isNumber(arg) { - return typeof arg === 'number'; +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; } -function isObject(arg) { - return typeof arg === 'object' && arg !== null; +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; } -function isUndefined(arg) { - return arg === void 0; -} +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); -},{}],"/node_modules/jshint/data/ascii-identifier-data.js":[function(_dereq_,module,exports){ -var identifierStartTable = []; + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} -for (var i = 0; i < 128; i++) { - identifierStartTable[i] = - i === 36 || // $ - i >= 65 && i <= 90 || // A-Z - i === 95 || // _ - i >= 97 && i <= 122; // a-z +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; } -var identifierPartTable = []; +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); -for (var i = 0; i < 128; i++) { - identifierPartTable[i] = - identifierStartTable[i] || // $, _, A-Z, a-z - i >= 48 && i <= 57; // 0-9 + set.forEach(function(value) { + result[++index] = value; + }); + return result; } -module.exports = { - asciiIdentifierStartTable: identifierStartTable, - asciiIdentifierPartTable: identifierPartTable -}; - -},{}],"/node_modules/jshint/lodash.js":[function(_dereq_,module,exports){ -(function (global){ -;(function() { - - var undefined; - - var VERSION = '3.7.0'; - - var FUNC_ERROR_TEXT = 'Expected a function'; - - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; - - var arrayBufferTag = '[object ArrayBuffer]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - var reIsDeepProp = /\.|\[(?:[^[\]]+|(["'])(?:(?!\1)[^\n\\]|\\.)*?)\1\]/, - reIsPlainProp = /^\w*$/, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; - - var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, - reHasRegExpChars = RegExp(reRegExpChars.source); - - var reEscapeChar = /\\(\\)?/g; - - var reFlags = /\w*$/; - - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dateTag] = typedArrayTags[errorTag] = - typedArrayTags[funcTag] = typedArrayTags[mapTag] = - typedArrayTags[numberTag] = typedArrayTags[objectTag] = - typedArrayTags[regexpTag] = typedArrayTags[setTag] = - typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; - - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = - cloneableTags[dateTag] = cloneableTags[float32Tag] = - cloneableTags[float64Tag] = cloneableTags[int8Tag] = - cloneableTags[int16Tag] = cloneableTags[int32Tag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[stringTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[mapTag] = cloneableTags[setTag] = - cloneableTags[weakMapTag] = false; - - var objectTypes = { - 'function': true, - 'object': true - }; +/** Used for built-in method references. */ +var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; - var freeSelf = objectTypes[typeof self] && self && self.Object && self; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - var freeWindow = objectTypes[typeof window] && window && window.Object && window; +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} - var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; +} - function baseFindIndex(array, predicate, fromRight) { - var length = array.length, - index = fromRight ? length : -1; +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; +} - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} - function baseIndexOf(array, value, fromIndex) { - if (value !== value) { - return indexOfNaN(array, fromIndex); - } - var index = fromIndex - 1, - length = array.length; +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); +} - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} - function baseIsFunction(value) { - return typeof value == 'function' || false; - } +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; - function baseToString(value) { - if (typeof value == 'string') { - return value; - } - return value == null ? '' : (value + ''); +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); } +} - function indexOfNaN(array, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 0 : -1); +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; +} - while ((fromRight ? index-- : ++index < length)) { - var other = array[index]; - if (other !== other) { - return index; - } - } - return -1; - } +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); - function isObjectLike(value) { - return !!value && typeof value == 'object'; + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); } + return true; +} - var arrayProto = Array.prototype, - objectProto = Object.prototype; +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); - var fnToString = Function.prototype.toString; + return index < 0 ? undefined : data[index][1]; +} - var hasOwnProperty = objectProto.hasOwnProperty; +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} - var objToString = objectProto.toString; +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); - var reIsNative = RegExp('^' + - escapeRegExp(objToString) - .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} - var ArrayBuffer = isNative(ArrayBuffer = root.ArrayBuffer) && ArrayBuffer, - bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice, - floor = Math.floor, - getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - push = arrayProto.push, - preventExtensions = isNative(Object.preventExtensions = Object.preventExtensions) && preventExtensions, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - Uint8Array = isNative(Uint8Array = root.Uint8Array) && Uint8Array; +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; - var Float64Array = (function() { - try { - var func = isNative(func = root.Float64Array) && func, - result = new func(new ArrayBuffer(10), 0, 1) && func; - } catch(e) {} - return result; - }()); +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} - var nativeAssign = (function() { - var object = { '1': 0 }, - func = preventExtensions && isNative(func = Object.assign) && func; +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} - try { func(preventExtensions(object), 'xo'); } catch(e) {} - return !object[1] && func; - }()); +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); +} - var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min; +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} - var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY; +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} - var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; +} - var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; - var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + this.__data__ = new ListCache(entries); +} - function lodash() { - } +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; +} - var support = lodash.support = {}; +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + return this.__data__['delete'](key); +} - (function(x) { - var Ctor = function() { this.x = x; }, - object = { '0': x, 'length': x }, - props = []; +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} - Ctor.prototype = { 'valueOf': x, 'y': x }; - for (var key in new Ctor) { props.push(key); } +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} - support.funcDecomp = /\bthis\b/.test(function() { return this; }); +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; +} - support.funcNames = typeof Function.name == 'string'; +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; - try { - support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1); - } catch(e) { - support.nonEnumArgs = true; - } - }(1, 0)); +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; - function arrayCopy(source, array) { - var index = -1, - length = source.length; + var length = result.length, + skipIndexes = !!length; - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); } - return array; } + return result; +} - function arrayEach(array, iteratee) { - var index = -1, - length = array.length; +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; } - return array; } + return -1; +} - function arrayFilter(array, predicate) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); +} - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[++resIndex] = value; - } - } +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { return result; } - - function arrayMap(array, iteratee) { - var index = -1, - length = array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; + if (!isObject(value)) { + return value; } - - function arrayMax(array) { - var index = -1, - length = array.length, - result = NEGATIVE_INFINITY; - - while (++index < length) { - var value = array[index]; - if (value > result) { - result = value; - } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); } - return result; - } - - function arraySome(array, predicate) { - var index = -1, - length = array.length; + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); } - return false; - } - - function assignWith(object, source, customizer) { - var props = keys(source); - push.apply(props, getSymbols(source)); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index], - value = object[key], - result = customizer(value, source[key], key, object, source); - - if ((result === result ? (result !== value) : (value === value)) || - (value === undefined && !(key in object))) { - object[key] = result; + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; } - } - return object; - } - - var baseAssign = nativeAssign || function(object, source) { - return source == null - ? object - : baseCopy(source, getSymbols(source), baseCopy(source, keys(source), object)); - }; - - function baseCopy(source, props, object) { - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - object[key] = source[key]; - } - return object; - } - - function baseCallback(func, thisArg, argCount) { - var type = typeof func; - if (type == 'function') { - return thisArg === undefined - ? func - : bindCallback(func, thisArg, argCount); - } - if (func == null) { - return identity; - } - if (type == 'object') { - return baseMatches(func); - } - return thisArg === undefined - ? property(func) - : baseMatchesProperty(func, thisArg); - } - - function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { - var result; - if (customizer) { - result = object ? customizer(value, key, object) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); + result = initCloneObject(isFunc ? {} : value); if (!isDeep) { - return arrayCopy(value, result); + return copySymbols(value, baseAssign(result, value)); } } else { - var tag = objToString.call(value), - isFunc = tag == funcTag; - - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = initCloneObject(isFunc ? {} : value); - if (!isDeep) { - return baseAssign(result, value); - } - } else { - return cloneableTags[tag] - ? initCloneByTag(value, tag, isDeep) - : (object ? value : {}); - } - } - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; + if (!cloneableTags[tag]) { + return object ? value : {}; } + result = initCloneByTag(value, tag, baseClone, isDeep); } - stackA.push(value); - stackB.push(result); + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); - (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { - result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); - }); - return result; + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; +} - var baseEach = createBaseEach(baseForOwn); +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; +} - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); +} - var baseFor = createBaseFor(); +/** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + return objectToString.call(value); +} - function baseForIn(object, iteratee) { - return baseFor(object, iteratee, keysIn); +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} - function baseForOwn(object, iteratee) { - return baseFor(object, iteratee, keys); +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); } - - function baseGet(object, path, pathKey) { - if (object == null) { - return; - } - if (pathKey !== undefined && pathKey in toObject(object)) { - path = [pathKey]; - } - var index = -1, - length = path.length; - - while (object != null && ++index < length) { - var result = object = object[path[index]]; + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); } - return result; } + return result; +} - function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { - if (value === other) { - return value !== 0 || (1 / value == 1 / other); - } - var valType = typeof value, - othType = typeof other; - - if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') || - value == null || other == null) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; +} - function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = arrayTag, - othTag = arrayTag; - - if (!objIsArr) { - objTag = objToString.call(object); - if (objTag == argsTag) { - objTag = objectTag; - } else if (objTag != objectTag) { - objIsArr = isTypedArray(object); - } - } - if (!othIsArr) { - othTag = objToString.call(other); - if (othTag == argsTag) { - othTag = objectTag; - } else if (othTag != objectTag) { - othIsArr = isTypedArray(other); - } - } - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && !(objIsArr || objIsObj)) { - return equalByTag(object, other, objTag); - } - if (!isLoose) { - var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} - if (valWrapped || othWrapped) { - return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); - } - } - if (!isSameTag) { - return false; - } - stackA || (stackA = []); - stackB || (stackB = []); +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} - var length = stackA.length; - while (length--) { - if (stackA[length] == object) { - return stackB[length] == other; - } - } - stackA.push(object); - stackB.push(other); +/** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ +function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); +} - var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} - stackA.pop(); - stackB.pop(); +/** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ +function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); +} - return result; - } +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} - function baseIsMatch(object, props, values, strictCompareFlags, customizer) { - var index = -1, - length = props.length, - noCustomizer = !customizer; +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} - while (++index < length) { - if ((noCustomizer && strictCompareFlags[index]) - ? values[index] !== object[props[index]] - : !(props[index] in object) - ) { - return false; - } - } - index = -1; - while (++index < length) { - var key = props[index], - objValue = object[key], - srcValue = values[index]; +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; - if (noCustomizer && strictCompareFlags[index]) { - var result = objValue !== undefined || (key in object); - } else { - result = customizer ? customizer(objValue, srcValue, key) : undefined; - if (result === undefined) { - result = baseIsEqual(srcValue, objValue, customizer, true); - } - } - if (!result) { - return false; - } - } - return true; + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; } + return array; +} - function baseMatches(source) { - var props = keys(source), - length = props.length; - - if (!length) { - return constant(true); - } - if (length == 1) { - var key = props[0], - value = source[key]; +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + object || (object = {}); - if (isStrictComparable(value)) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === value && (value !== undefined || (key in toObject(object))); - }; - } - } - var values = Array(length), - strictCompareFlags = Array(length); + var index = -1, + length = props.length; - while (length--) { - value = source[props[length]]; - values[length] = value; - strictCompareFlags[length] = isStrictComparable(value); - } - return function(object) { - return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags); - }; - } + while (++index < length) { + var key = props[index]; - function baseMatchesProperty(path, value) { - var isArr = isArray(path), - isCommon = isKey(path) && isStrictComparable(value), - pathKey = (path + ''); + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; - path = toPath(path); - return function(object) { - if (object == null) { - return false; - } - var key = pathKey; - object = toObject(object); - if ((isArr || !isCommon) && !(key in object)) { - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - if (object == null) { - return false; - } - key = last(path); - object = toObject(object); - } - return object[key] === value - ? (value !== undefined || (key in object)) - : baseIsEqual(value, object[key], null, true); - }; + assignValue(object, key, newValue === undefined ? source[key] : newValue); } + return object; +} - function baseMerge(object, source, customizer, stackA, stackB) { - if (!isObject(object)) { - return object; - } - var isSrcArr = isLength(source.length) && (isArray(source) || isTypedArray(source)); - if (!isSrcArr) { - var props = keys(source); - push.apply(props, getSymbols(source)); - } - arrayEach(props || source, function(srcValue, key) { - if (props) { - key = srcValue; - srcValue = source[key]; - } - if (isObjectLike(srcValue)) { - stackA || (stackA = []); - stackB || (stackB = []); - baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); - } - else { - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; +/** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} - if (isCommon) { - result = srcValue; - } - if ((isSrcArr || result !== undefined) && - (isCommon || (result === result ? (result !== value) : (value === value)))) { - object[key] = result; - } - } - }); - return object; - } +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); +} - function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { - var length = stackA.length, - srcValue = source[key]; +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} - while (length--) { - if (stackA[length] == srcValue) { - object[key] = stackB[length]; - return; - } - } - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} - if (isCommon) { - result = srcValue; - if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) { - result = isArray(value) - ? value - : (getLength(value) ? arrayCopy(value) : []); - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - result = isArguments(value) - ? toPlainObject(value) - : (isPlainObject(value) ? value : {}); - } - else { - isCommon = false; - } - } - stackA.push(srcValue); - stackB.push(result); +/** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; - if (isCommon) { - object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); - } else if (result === result ? (result !== value) : (value === value)) { - object[key] = result; +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; + +// Fallback for data views, maps, sets, and weak maps in IE 11, +// for data views in Edge < 14, and promises in Node.js. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } } - } - - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } + return result; + }; +} - function basePropertyDeep(path) { - var pathKey = (path + ''); - path = toPath(path); - return function(object) { - return baseGet(object, path, pathKey); - }; +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; } + return result; +} - function baseSlice(array, start, end) { - var index = -1, - length = array.length; +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; +} - start = start == null ? 0 : (+start || 0); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } + case boolTag: + case dateTag: + return new Ctor(+object); - function baseSome(collection, predicate) { - var result; + case dataViewTag: + return cloneDataView(object, isDeep); - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; - } + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); - function baseValues(object, props) { - var index = -1, - length = props.length, - result = Array(length); + case mapTag: + return cloneMap(object, isDeep, cloneFunc); - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } + case numberTag: + case stringTag: + return new Ctor(object); - function binaryIndex(array, value, retHighest) { - var low = 0, - high = array ? array.length : low; + case regexpTag: + return cloneRegExp(object); - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; + case setTag: + return cloneSet(object, isDeep, cloneFunc); - if (retHighest ? (computed <= value) : (computed < value)) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return binaryIndexBy(array, value, identity, retHighest); + case symbolTag: + return cloneSymbol(object); } +} - function binaryIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} - var low = 0, - high = array ? array.length : 0, - valIsNaN = value !== value, - valIsUndef = value === undefined; - - while (low < high) { - var mid = floor((low + high) / 2), - computed = iteratee(array[mid]), - isReflexive = computed === computed; - - if (valIsNaN) { - var setLow = isReflexive || retHighest; - } else if (valIsUndef) { - setLow = isReflexive && (retHighest || computed !== undefined); - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); - } - - function bindCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - if (thisArg === undefined) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - case 5: return function(value, other, key, object, source) { - return func.call(thisArg, value, other, key, object, source); - }; - } - return function() { - return func.apply(thisArg, arguments); - }; - } - - function bufferClone(buffer) { - return bufferSlice.call(buffer, 0); - } - if (!bufferSlice) { - bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { - var byteLength = buffer.byteLength, - floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, - offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, - result = new ArrayBuffer(byteLength); - - if (floatLength) { - var view = new Float64Array(result, 0, floatLength); - view.set(new Float64Array(buffer, 0, floatLength)); - } - if (byteLength != offset) { - view = new Uint8Array(result, offset); - view.set(new Uint8Array(buffer, offset)); - } - return result; - }; - } +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} - function createAssigner(assigner) { - return restParam(function(object, sources) { - var index = -1, - length = object == null ? 0 : sources.length, - customizer = length > 2 && sources[length - 2], - guard = length > 2 && sources[2], - thisArg = length > 1 && sources[length - 1]; +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} - if (typeof customizer == 'function') { - customizer = bindCallback(customizer, thisArg, 5); - length -= 2; - } else { - customizer = typeof thisArg == 'function' ? thisArg : null; - length -= (customizer ? 1 : 0); - } - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? null : customizer; - length = 1; - } - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, customizer); - } - } - return object; - }); - } +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { - return eachFunc(collection, iteratee); - } - var index = fromRight ? length : -1, - iterable = toObject(collection); + return value === proto; +} - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} } + return ''; +} - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var iterable = toObject(object), - props = keysFunc(object), - length = props.length, - index = fromRight ? length : -1; +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return baseClone(value, false, true); +} - while ((fromRight ? index-- : ++index < length)) { - var key = props[index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} - function createFindIndex(fromRight) { - return function(array, predicate, thisArg) { - if (!(array && array.length)) { - return -1; - } - predicate = getCallback(predicate, thisArg, 3); - return baseFindIndex(array, predicate, fromRight); - }; - } +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} - function createForEach(arrayFunc, eachFunc) { - return function(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee) - : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); - }; - } +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; - function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { - var index = -1, - arrLength = array.length, - othLength = other.length, - result = true; +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} - if (arrLength != othLength && !(isLoose && othLength > arrLength)) { - return false; - } - while (result && ++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - result = undefined; - if (customizer) { - result = isLoose - ? customizer(othValue, arrValue, index) - : customizer(arrValue, othValue, index); - } - if (result === undefined) { - if (isLoose) { - var othIndex = othLength; - while (othIndex--) { - othValue = other[othIndex]; - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); - if (result) { - break; - } - } - } else { - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); - } - } - } - return !!result; - } +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} - function equalByTag(object, other, tag) { - switch (tag) { - case boolTag: - case dateTag: - return +object == +other; +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; - case errorTag: - return object.name == other.name && object.message == other.message; +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} - case numberTag: - return (object != +object) - ? other != +other - : (object == 0 ? ((1 / object) == (1 / other)) : object == +other); +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} - case regexpTag: - case stringTag: - return object == (other + ''); - } - return false; - } +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} - function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { - var objProps = keys(object), - objLength = objProps.length, - othProps = keys(other), - othLength = othProps.length; +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} - if (objLength != othLength && !isLoose) { - return false; - } - var skipCtor = isLoose, - index = -1; +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} - while (++index < objLength) { - var key = objProps[index], - result = isLoose ? key in other : hasOwnProperty.call(other, key); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} - if (result) { - var objValue = object[key], - othValue = other[key]; +/** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ +function stubFalse() { + return false; +} - result = undefined; - if (customizer) { - result = isLoose - ? customizer(othValue, objValue, key) - : customizer(objValue, othValue, key); - } - if (result === undefined) { - result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB); - } - } - if (!result) { - return false; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (!skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; +module.exports = clone; - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - return false; - } - } - return true; - } +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],"/../../../jshint/node_modules/lodash.slice/index.js":[function(_dereq_,module,exports){ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ - function getCallback(func, thisArg, argCount) { - var result = lodash.callback || callback; - result = result === callback ? baseCallback : result; - return argCount ? result(func, thisArg, argCount) : result; - } +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; - function getIndexOf(collection, target, fromIndex) { - var result = lodash.indexOf || indexOf; - result = result === indexOf ? baseIndexOf : result; - return collection ? result(collection, target, fromIndex) : result; - } +/** `Object#toString` result references. */ +var funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + symbolTag = '[object Symbol]'; - var getLength = baseProperty('length'); +/** Used to match leading and trailing whitespace. */ +var reTrim = /^\s+|\s+$/g; - var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) { - return getOwnPropertySymbols(toObject(object)); - }; +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - function initCloneArray(array) { - var length = array.length, - result = new array.constructor(length); +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; - } +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; - function initCloneObject(object) { - var Ctor = object.constructor; - if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { - Ctor = Object; - } - return new Ctor; - } +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; - function initCloneByTag(object, tag, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return bufferClone(object); +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; - case boolTag: - case dateTag: - return new Ctor(+object); +/** Used for built-in method references. */ +var objectProto = Object.prototype; - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - var buffer = object.buffer; - return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; - case numberTag: - case stringTag: - return new Ctor(object); +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; - case regexpTag: - var result = new Ctor(object.source, reFlags.exec(object)); - result.lastIndex = object.lastIndex; - } - return result; + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; - function isIndex(value, length) { - value = +value; - length = length == null ? MAX_SAFE_INTEGER : length; - return value > -1 && value % 1 == 0 && value < length; + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; } + return result; +} - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number') { - var length = getLength(object), - prereq = isLength(length) && isIndex(index, length); - } else { - prereq = type == 'string' && index in object; - } - if (prereq) { - var other = object[index]; - return value === value ? (value === other) : (other !== other); - } +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { return false; } - - function isKey(value, object) { - var type = typeof value; - if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { - return true; - } - if (isArray(value)) { - return false; - } - var result = !reIsDeepProp.test(value); - return result || (object != null && value in toObject(object)); + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); } + return false; +} - function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +/** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of + * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are + * returned. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; } - - function isStrictComparable(value) { - return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value)); + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; } - - function shimIsPlainObject(value) { - var Ctor, - support = lodash.support; - - if (!(isObjectLike(value) && objToString.call(value) == objectTag) || - (!hasOwnProperty.call(value, 'constructor') && - (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { - return false; - } - var result; - baseForIn(value, function(subValue, key) { - result = key; - }); - return result === undefined || hasOwnProperty.call(value, result); + else { + start = start == null ? 0 : toInteger(start); + end = end === undefined ? length : toInteger(end); } + return baseSlice(array, start, end); +} - function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length, - support = lodash.support; - - var allowIndexes = length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))); - - var index = -1, - result = []; - - while (++index < propsLength) { - var key = props[index]; - if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { - result.push(key); - } - } - return result; +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; } + return value === value ? value : 0; +} + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; - function toObject(value) { - return isObject(value) ? value : Object(value); + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} - function toPath(value) { - if (isArray(value)) { - return value; - } - var result = []; - baseToString(value).replace(rePropName, function(match, number, quote, string) { - result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; +module.exports = slice; + +},{}],"/../../../jshint/node_modules/underscore/underscore-umd.js":[function(_dereq_,module,exports){ +(function (global){ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define('underscore', factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () { + var current = global._; + var exports = global._ = factory(); + exports.noConflict = function () { global._ = current; return exports; }; + }())); +}(this, (function () { + // Underscore.js 1.13.6 + // https://underscorejs.org + // (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors + // Underscore may be freely distributed under the MIT license. + + // Current version. + var VERSION = '1.13.6'; + + // Establish the root object, `window` (`self`) in the browser, `global` + // on the server, or `this` in some virtual machines. We use `self` + // instead of `window` for `WebWorker` support. + var root = (typeof self == 'object' && self.self === self && self) || + (typeof global == 'object' && global.global === global && global) || + Function('return this')() || + {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype; + var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; + + // Create quick reference variables for speed access to core prototypes. + var push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // Modern feature detection. + var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined', + supportsDataView = typeof DataView !== 'undefined'; + + // All **ECMAScript 5+** native function implementations that we hope to use + // are declared here. + var nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeCreate = Object.create, + nativeIsView = supportsArrayBuffer && ArrayBuffer.isView; + + // Create references to these builtin functions because we override them. + var _isNaN = isNaN, + _isFinite = isFinite; + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + // The largest integer that can be represented exactly. + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + + // Some functions take a variable number of arguments, or a few expected + // arguments at the beginning and then a variable number of values to operate + // on. This helper accumulates all remaining arguments past the function’s + // argument length (or an explicit `startIndex`), into an array that becomes + // the last argument. Similar to ES6’s "rest parameter". + function restArguments(func, startIndex) { + startIndex = startIndex == null ? func.length - 1 : +startIndex; + return function() { + var length = Math.max(arguments.length - startIndex, 0), + rest = Array(length), + index = 0; + for (; index < length; index++) { + rest[index] = arguments[index + startIndex]; + } + switch (startIndex) { + case 0: return func.call(this, rest); + case 1: return func.call(this, arguments[0], rest); + case 2: return func.call(this, arguments[0], arguments[1], rest); + } + var args = Array(startIndex + 1); + for (index = 0; index < startIndex; index++) { + args[index] = arguments[index]; + } + args[startIndex] = rest; + return func.apply(this, args); + }; } - var findLastIndex = createFindIndex(true); + // Is a given variable an object? + function isObject(obj) { + var type = typeof obj; + return type === 'function' || (type === 'object' && !!obj); + } - function indexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - if (typeof fromIndex == 'number') { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; - } else if (fromIndex) { - var index = binaryIndex(array, value), - other = array[index]; + // Is a given value equal to null? + function isNull(obj) { + return obj === null; + } - if (value === value ? (value === other) : (other !== other)) { - return index; - } - return -1; - } - return baseIndexOf(array, value, fromIndex || 0); + // Is a given variable undefined? + function isUndefined(obj) { + return obj === void 0; } - function last(array) { - var length = array ? array.length : 0; - return length ? array[length - 1] : undefined; + // Is a given value a boolean? + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; } - function slice(array, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; - } - return baseSlice(array, start, end); + // Is a given value a DOM element? + function isElement(obj) { + return !!(obj && obj.nodeType === 1); } - function unzip(array) { - var index = -1, - length = (array && array.length && arrayMax(arrayMap(array, getLength))) >>> 0, - result = Array(length); + // Internal function for creating a `toString`-based type tester. + function tagTester(name) { + var tag = '[object ' + name + ']'; + return function(obj) { + return toString.call(obj) === tag; + }; + } - while (++index < length) { - result[index] = arrayMap(array, baseProperty(index)); - } - return result; + var isString = tagTester('String'); + + var isNumber = tagTester('Number'); + + var isDate = tagTester('Date'); + + var isRegExp = tagTester('RegExp'); + + var isError = tagTester('Error'); + + var isSymbol = tagTester('Symbol'); + + var isArrayBuffer = tagTester('ArrayBuffer'); + + var isFunction = tagTester('Function'); + + // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old + // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). + var nodelist = root.document && root.document.childNodes; + if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') { + isFunction = function(obj) { + return typeof obj == 'function' || false; + }; } - var zip = restParam(unzip); + var isFunction$1 = isFunction; - var forEach = createForEach(arrayEach, baseEach); + var hasObjectTag = tagTester('Object'); - function includes(collection, target, fromIndex, guard) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { - collection = values(collection); - length = collection.length; - } - if (!length) { - return false; - } - if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { - fromIndex = 0; - } else { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); - } - return (typeof collection == 'string' || !isArray(collection) && isString(collection)) - ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) - : (getIndexOf(collection, target, fromIndex) > -1); + // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`. + // In IE 11, the most common among them, this problem also applies to + // `Map`, `WeakMap` and `Set`. + var hasStringTagBug = ( + supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8))) + ), + isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map)); + + var isDataView = tagTester('DataView'); + + // In IE 10 - Edge 13, we need a different heuristic + // to determine whether an object is a `DataView`. + function ie10IsDataView(obj) { + return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer); } - function reject(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); - return func(collection, function(value, index, collection) { - return !predicate(value, index, collection); - }); + var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView); + + // Is a given value an array? + // Delegates to ECMA5's native `Array.isArray`. + var isArray = nativeIsArray || tagTester('Array'); + + // Internal function to check whether `key` is an own property name of `obj`. + function has$1(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); } - function some(collection, predicate, thisArg) { - var func = isArray(collection) ? arraySome : baseSome; - if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = null; - } - if (typeof predicate != 'function' || thisArg !== undefined) { - predicate = getCallback(predicate, thisArg, 3); + var isArguments = tagTester('Arguments'); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + (function() { + if (!isArguments(arguments)) { + isArguments = function(obj) { + return has$1(obj, 'callee'); + }; } - return func(collection, predicate); + }()); + + var isArguments$1 = isArguments; + + // Is a given object a finite number? + function isFinite$1(obj) { + return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj)); } - function restParam(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + // Is the given value `NaN`? + function isNaN$1(obj) { + return isNumber(obj) && _isNaN(obj); + } + + // Predicate-generating function. Often useful outside of Underscore. + function constant(value) { return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - rest = Array(length); + return value; + }; + } - while (++index < length) { - rest[index] = args[start + index]; - } - switch (start) { - case 0: return func.call(this, rest); - case 1: return func.call(this, args[0], rest); - case 2: return func.call(this, args[0], args[1], rest); - } - var otherArgs = Array(start + 1); - index = -1; - while (++index < start) { - otherArgs[index] = args[index]; + // Common internal logic for `isArrayLike` and `isBufferLike`. + function createSizePropertyCheck(getSizeProperty) { + return function(collection) { + var sizeProperty = getSizeProperty(collection); + return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX; + } + } + + // Internal helper to generate a function to obtain property `key` from `obj`. + function shallowProperty(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + } + + // Internal helper to obtain the `byteLength` property of an object. + var getByteLength = shallowProperty('byteLength'); + + // Internal helper to determine whether we should spend extensive checks against + // `ArrayBuffer` et al. + var isBufferLike = createSizePropertyCheck(getByteLength); + + // Is a given value a typed array? + var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/; + function isTypedArray(obj) { + // `ArrayBuffer.isView` is the most future-proof, so use it when available. + // Otherwise, fall back on the above regular expression. + return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) : + isBufferLike(obj) && typedArrayPattern.test(toString.call(obj)); + } + + var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false); + + // Internal helper to obtain the `length` property of an object. + var getLength = shallowProperty('length'); + + // Internal helper to create a simple lookup structure. + // `collectNonEnumProps` used to depend on `_.contains`, but this led to + // circular imports. `emulatedSet` is a one-off solution that only works for + // arrays of strings. + function emulatedSet(keys) { + var hash = {}; + for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true; + return { + contains: function(key) { return hash[key] === true; }, + push: function(key) { + hash[key] = true; + return keys.push(key); } - otherArgs[start] = rest; - return func.apply(this, otherArgs); }; } - function clone(value, isDeep, customizer, thisArg) { - if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { - isDeep = false; - } - else if (typeof isDeep == 'function') { - thisArg = customizer; - customizer = isDeep; - isDeep = false; + // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't + // be iterated by `for key in ...` and thus missed. Extends `keys` in place if + // needed. + function collectNonEnumProps(obj, keys) { + keys = emulatedSet(keys); + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (isFunction$1(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) { + keys.push(prop); + } } - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); - return baseClone(value, isDeep, customizer); } - function isArguments(value) { - var length = isObjectLike(value) ? value.length : undefined; - return isLength(length) && objToString.call(value) == argsTag; + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys`. + function keys(obj) { + if (!isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (has$1(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; } - var isArray = nativeIsArray || function(value) { - return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; - }; + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + function isEmpty(obj) { + if (obj == null) return true; + // Skip the more expensive `toString`-based type checks if `obj` has no + // `.length`. + var length = getLength(obj); + if (typeof length == 'number' && ( + isArray(obj) || isString(obj) || isArguments$1(obj) + )) return length === 0; + return getLength(keys(obj)) === 0; + } - function isEmpty(value) { - if (value == null) { - return true; - } - var length = getLength(value); - if (isLength(length) && (isArray(value) || isString(value) || isArguments(value) || - (isObjectLike(value) && isFunction(value.splice)))) { - return !length; + // Returns whether an object has a given set of `key:value` pairs. + function isMatch(object, attrs) { + var _keys = keys(attrs), length = _keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = _keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; } - return !keys(value).length; + return true; + } + + // If Underscore is called as a function, it returns a wrapped object that can + // be used OO-style. This wrapper holds altered versions of all functions added + // through `_.mixin`. Wrapped objects may be chained. + function _$1(obj) { + if (obj instanceof _$1) return obj; + if (!(this instanceof _$1)) return new _$1(obj); + this._wrapped = obj; } - var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) { - return objToString.call(value) == funcTag; + _$1.VERSION = VERSION; + + // Extracts the result from a wrapped and chained object. + _$1.prototype.value = function() { + return this._wrapped; }; - function isObject(value) { - var type = typeof value; - return type == 'function' || (!!value && type == 'object'); - } + // Provide unwrapping proxies for some methods used in engine operations + // such as arithmetic and JSON stringification. + _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value; - function isNative(value) { - if (value == null) { - return false; - } - if (objToString.call(value) == funcTag) { - return reIsNative.test(fnToString.call(value)); - } - return isObjectLike(value) && reIsHostCtor.test(value); + _$1.prototype.toString = function() { + return String(this._wrapped); + }; + + // Internal function to wrap or shallow-copy an ArrayBuffer, + // typed array or DataView to a new view, reusing the buffer. + function toBufferView(bufferSource) { + return new Uint8Array( + bufferSource.buffer || bufferSource, + bufferSource.byteOffset || 0, + getByteLength(bufferSource) + ); } - function isNumber(value) { - return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); + // We use this string twice, so give it a name for minification. + var tagDataView = '[object DataView]'; + + // Internal recursive comparison function for `_.isEqual`. + function eq(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // `null` or `undefined` only equal to itself (strict comparison). + if (a == null || b == null) return false; + // `NaN`s are equivalent, but non-reflexive. + if (a !== a) return b !== b; + // Exhaust primitive checks + var type = typeof a; + if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; + return deepEq(a, b, aStack, bStack); } - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && objToString.call(value) == objectTag)) { - return false; + // Internal recursive comparison function for `_.isEqual`. + function deepEq(a, b, aStack, bStack) { + // Unwrap any wrapped objects. + if (a instanceof _$1) a = a._wrapped; + if (b instanceof _$1) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + // Work around a bug in IE 10 - Edge 13. + if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) { + if (!isDataView$1(b)) return false; + className = tagDataView; + } + switch (className) { + // These types are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN. + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + case '[object Symbol]': + return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); + case '[object ArrayBuffer]': + case tagDataView: + // Coerce to typed array so we can fall through. + return deepEq(toBufferView(a), toBufferView(b), aStack, bStack); + } + + var areArrays = className === '[object Array]'; + if (!areArrays && isTypedArray$1(a)) { + var byteLength = getByteLength(a); + if (byteLength !== getByteLength(b)) return false; + if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true; + areArrays = true; + } + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && + isFunction$1(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } - function isString(value) { - return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var _keys = keys(a), key; + length = _keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = _keys[length]; + if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; } - function isTypedArray(value) { - return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; + // Perform a deep comparison to check if two objects are equal. + function isEqual(a, b) { + return eq(a, b); } - function toPlainObject(value) { - return baseCopy(value, keysIn(value)); + // Retrieve all the enumerable property names of an object. + function allKeys(obj) { + if (!isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; } - var assign = createAssigner(function(object, source, customizer) { - return customizer - ? assignWith(object, source, customizer) - : baseAssign(object, source); - }); + // Since the regular `Object.prototype.toString` type tests don't work for + // some types in IE 11, we use a fingerprinting heuristic instead, based + // on the methods. It's not great, but it's the best we got. + // The fingerprint method lists are defined below. + function ie11fingerprint(methods) { + var length = getLength(methods); + return function(obj) { + if (obj == null) return false; + // `Map`, `WeakMap` and `Set` have no enumerable keys. + var keys = allKeys(obj); + if (getLength(keys)) return false; + for (var i = 0; i < length; i++) { + if (!isFunction$1(obj[methods[i]])) return false; + } + // If we are testing against `WeakMap`, we need to ensure that + // `obj` doesn't have a `forEach` method in order to distinguish + // it from a regular `Map`. + return methods !== weakMapMethods || !isFunction$1(obj[forEachName]); + }; + } - function has(object, path) { - if (object == null) { - return false; - } - var result = hasOwnProperty.call(object, path); - if (!result && !isKey(path)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - path = last(path); - result = object != null && hasOwnProperty.call(object, path); + // In the interest of compact minification, we write + // each string in the fingerprints only once. + var forEachName = 'forEach', + hasName = 'has', + commonInit = ['clear', 'delete'], + mapTail = ['get', hasName, 'set']; + + // `Map`, `WeakMap` and `Set` each have slightly different + // combinations of the above sublists. + var mapMethods = commonInit.concat(forEachName, mapTail), + weakMapMethods = commonInit.concat(mapTail), + setMethods = ['add'].concat(commonInit, forEachName, hasName); + + var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map'); + + var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap'); + + var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set'); + + var isWeakSet = tagTester('WeakSet'); + + // Retrieve the values of an object's properties. + function values(obj) { + var _keys = keys(obj); + var length = _keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[_keys[i]]; } - return result; + return values; } - var keys = !nativeKeys ? shimKeys : function(object) { - if (object) { - var Ctor = object.constructor, - length = object.length; - } - if ((typeof Ctor == 'function' && Ctor.prototype === object) || - (typeof object != 'function' && isLength(length))) { - return shimKeys(object); + // Convert an object into a list of `[key, value]` pairs. + // The opposite of `_.object` with one argument. + function pairs(obj) { + var _keys = keys(obj); + var length = _keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [_keys[i], obj[_keys[i]]]; } - return isObject(object) ? nativeKeys(object) : []; - }; + return pairs; + } - function keysIn(object) { - if (object == null) { - return []; + // Invert the keys and values of an object. The values must be serializable. + function invert(obj) { + var result = {}; + var _keys = keys(obj); + for (var i = 0, length = _keys.length; i < length; i++) { + result[obj[_keys[i]]] = _keys[i]; } - if (!isObject(object)) { - object = Object(object); - } - var length = object.length; - length = (length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; - - var Ctor = object.constructor, - index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype === object, - result = Array(length), - skipIndexes = length > 0; + return result; + } - while (++index < length) { - result[index] = (index + ''); + // Return a sorted list of the function names available on the object. + function functions(obj) { + var names = []; + for (var key in obj) { + if (isFunction$1(obj[key])) names.push(key); } - for (var key in object) { - if (!(skipIndexes && isIndex(key, length)) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); + return names.sort(); + } + + // An internal function for creating assigner functions. + function createAssigner(keysFunc, defaults) { + return function(obj) { + var length = arguments.length; + if (defaults) obj = Object(obj); + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!defaults || obj[key] === void 0) obj[key] = source[key]; + } } - } + return obj; + }; + } + + // Extend a given object with all the properties in passed-in object(s). + var extend = createAssigner(allKeys); + + // Assigns a given object with all the own properties in the passed-in + // object(s). + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + var extendOwn = createAssigner(keys); + + // Fill in a given object with default properties. + var defaults = createAssigner(allKeys, true); + + // Create a naked function reference for surrogate-prototype-swapping. + function ctor() { + return function(){}; + } + + // An internal function for creating a new object that inherits from another. + function baseCreate(prototype) { + if (!isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + var Ctor = ctor(); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + } + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + function create(prototype, props) { + var result = baseCreate(prototype); + if (props) extendOwn(result, props); return result; } - var merge = createAssigner(baseMerge); + // Create a (shallow-cloned) duplicate of an object. + function clone(obj) { + if (!isObject(obj)) return obj; + return isArray(obj) ? obj.slice() : extend({}, obj); + } + + // Invokes `interceptor` with the `obj` and then returns `obj`. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + function tap(obj, interceptor) { + interceptor(obj); + return obj; + } - function values(object) { - return baseValues(object, keys(object)); + // Normalize a (deep) property `path` to array. + // Like `_.iteratee`, this function can be customized. + function toPath$1(path) { + return isArray(path) ? path : [path]; } + _$1.toPath = toPath$1; - function escapeRegExp(string) { - string = baseToString(string); - return (string && reHasRegExpChars.test(string)) - ? string.replace(reRegExpChars, '\\$&') - : string; + // Internal wrapper for `_.toPath` to enable minification. + // Similar to `cb` for `_.iteratee`. + function toPath(path) { + return _$1.toPath(path); } - function callback(func, thisArg, guard) { - if (guard && isIterateeCall(func, thisArg, guard)) { - thisArg = null; + // Internal function to obtain a nested property in `obj` along `path`. + function deepGet(obj, path) { + var length = path.length; + for (var i = 0; i < length; i++) { + if (obj == null) return void 0; + obj = obj[path[i]]; } - return baseCallback(func, thisArg); + return length ? obj : void 0; } - function constant(value) { - return function() { - return value; - }; + // Get the value of the (deep) property on `path` from `object`. + // If any property in `path` does not exist or if the value is + // `undefined`, return `defaultValue` instead. + // The `path` is normalized through `_.toPath`. + function get(object, path, defaultValue) { + var value = deepGet(object, toPath(path)); + return isUndefined(value) ? defaultValue : value; + } + + // Shortcut function for checking if an object has a given property directly on + // itself (in other words, not on a prototype). Unlike the internal `has` + // function, this public version can also traverse nested properties. + function has(obj, path) { + path = toPath(path); + var length = path.length; + for (var i = 0; i < length; i++) { + var key = path[i]; + if (!has$1(obj, key)) return false; + obj = obj[key]; + } + return !!length; } + // Keep the identity function around for default iteratees. function identity(value) { return value; } - function property(path) { - return isKey(path) ? baseProperty(path) : basePropertyDeep(path); - } - - // Add functions that return wrapped values when chaining. - lodash.assign = assign; - lodash.callback = callback; - lodash.constant = constant; - lodash.forEach = forEach; - lodash.keys = keys; - lodash.keysIn = keysIn; - lodash.merge = merge; - lodash.property = property; - lodash.reject = reject; - lodash.restParam = restParam; - lodash.slice = slice; - lodash.toPlainObject = toPlainObject; - lodash.unzip = unzip; - lodash.values = values; - lodash.zip = zip; - - lodash.each = forEach; - lodash.extend = assign; - lodash.iteratee = callback; - - // Add functions that return unwrapped values when chaining. - lodash.clone = clone; - lodash.escapeRegExp = escapeRegExp; - lodash.findLastIndex = findLastIndex; - lodash.has = has; - lodash.identity = identity; - lodash.includes = includes; - lodash.indexOf = indexOf; - lodash.isArguments = isArguments; - lodash.isArray = isArray; - lodash.isEmpty = isEmpty; - lodash.isFunction = isFunction; - lodash.isNative = isNative; - lodash.isNumber = isNumber; - lodash.isObject = isObject; - lodash.isPlainObject = isPlainObject; - lodash.isString = isString; - lodash.isTypedArray = isTypedArray; - lodash.last = last; - lodash.some = some; - - lodash.any = some; - lodash.contains = includes; - lodash.include = includes; - - lodash.VERSION = VERSION; - - // Some AMD build optimizers like r.js check for condition patterns like the following: - if (freeExports && freeModule) { - if (moduleExports) { - (freeModule.exports = lodash)._ = lodash; - } - else { - freeExports._ = lodash; - } - } - else { - root._ = lodash; + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + function matcher(attrs) { + attrs = extendOwn({}, attrs); + return function(obj) { + return isMatch(obj, attrs); + }; } -}.call(this)); -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],"/node_modules/jshint/src/jshint.js":[function(_dereq_,module,exports){ -/*! - * JSHint, by JSHint Community. - * - * This file (and this file only) is licensed under the same slightly modified - * MIT license that JSLint is. It stops evil-doers everywhere: - * - * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) - * - * 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: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * The Software shall be used for Good, not Evil. - * - * 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. - * - */ + // Creates a function that, when passed an object, will traverse that object’s + // properties down the given `path`, specified as an array of keys or indices. + function property(path) { + path = toPath(path); + return function(obj) { + return deepGet(obj, path); + }; + } -/*jshint quotmark:double */ -/*global console:true */ -/*exported console */ + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + function optimizeCb(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + // The 2-argument case is omitted because we’re not using it. + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + } -var _ = _dereq_("../lodash"); -var events = _dereq_("events"); -var vars = _dereq_("./vars.js"); -var messages = _dereq_("./messages.js"); -var Lexer = _dereq_("./lex.js").Lexer; -var reg = _dereq_("./reg.js"); -var state = _dereq_("./state.js").state; -var style = _dereq_("./style.js"); -var options = _dereq_("./options.js"); -var scopeManager = _dereq_("./scope-manager.js"); + // An internal function to generate callbacks that can be applied to each + // element in a collection, returning the desired result — either `_.identity`, + // an arbitrary callback, a property matcher, or a property accessor. + function baseIteratee(value, context, argCount) { + if (value == null) return identity; + if (isFunction$1(value)) return optimizeCb(value, context, argCount); + if (isObject(value) && !isArray(value)) return matcher(value); + return property(value); + } -// We build the application inside a function so that we produce only a singleton -// variable. That function will be invoked immediately, and its return value is -// the JSHINT function itself. + // External wrapper for our callback generator. Users may customize + // `_.iteratee` if they want additional predicate/iteratee shorthand styles. + // This abstraction hides the internal-only `argCount` argument. + function iteratee(value, context) { + return baseIteratee(value, context, Infinity); + } + _$1.iteratee = iteratee; -var JSHINT = (function() { - "use strict"; + // The function we call internally to generate a callback. It invokes + // `_.iteratee` if overridden, otherwise `baseIteratee`. + function cb(value, context, argCount) { + if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context); + return baseIteratee(value, context, argCount); + } - var api, // Extension API + // Returns the results of applying the `iteratee` to each element of `obj`. + // In contrast to `_.map` it returns an object. + function mapObject(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var _keys = keys(obj), + length = _keys.length, + results = {}; + for (var index = 0; index < length; index++) { + var currentKey = _keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + } - // These are operators that should not be used with the ! operator. - bang = { - "<" : true, - "<=" : true, - "==" : true, - "===": true, - "!==": true, - "!=" : true, - ">" : true, - ">=" : true, - "+" : true, - "-" : true, - "*" : true, - "/" : true, - "%" : true - }, + // Predicate-generating function. Often useful outside of Underscore. + function noop(){} - declared, // Globals that were declared using /*global ... */ syntax. + // Generates a function for a given object that returns a given property. + function propertyOf(obj) { + if (obj == null) return noop; + return function(path) { + return get(obj, path); + }; + } - functionicity = [ - "closure", "exception", "global", "label", - "outer", "unused", "var" - ], + // Run a function **n** times. + function times(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + } - functions, // All of the functions + // Return a random integer between `min` and `max` (inclusive). + function random(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + } - inblock, - indent, - lookahead, - lex, - member, - membersOnly, - predefined, // Global variables defined by option + // A (possibly faster) way to get the current timestamp as an integer. + var now = Date.now || function() { + return new Date().getTime(); + }; - stack, - urls, + // Internal helper to generate functions for escaping and unescaping strings + // to/from HTML interpolation. + function createEscaper(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped. + var source = '(?:' + keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + } - extraModules = [], - emitter = new events.EventEmitter(); + // Internal list of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; - function checkOption(name, t) { - name = name.trim(); + // Function for escaping strings to HTML interpolation. + var _escape = createEscaper(escapeMap); - if (/^[+-]W\d{3}$/g.test(name)) { - return true; - } + // Internal list of HTML entities for unescaping. + var unescapeMap = invert(escapeMap); - if (options.validNames.indexOf(name) === -1) { - if (t.type !== "jslint" && !_.has(options.removed, name)) { - error("E001", t, name); - return false; - } - } + // Function for unescaping strings from HTML interpolation. + var _unescape = createEscaper(unescapeMap); - return true; - } + // By default, Underscore uses ERB-style template delimiters. Change the + // following template settings to use alternative delimiters. + var templateSettings = _$1.templateSettings = { + evaluate: /<%([\s\S]+?)%>/g, + interpolate: /<%=([\s\S]+?)%>/g, + escape: /<%-([\s\S]+?)%>/g + }; - function isString(obj) { - return Object.prototype.toString.call(obj) === "[object String]"; - } + // When customizing `_.templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; - function isIdentifier(tkn, value) { - if (!tkn) - return false; + var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; - if (!tkn.identifier || tkn.value !== value) - return false; + function escapeChar(match) { + return '\\' + escapes[match]; + } - return true; + // In order to prevent third-party code injection through + // `_.templateSettings.variable`, we test it against the following regular + // expression. It is intentionally a bit more liberal than just matching valid + // identifiers, but still prevents possible loopholes through defaults or + // destructuring assignment. + var bareIdentifier = /^\s*(\w|\$)+\s*$/; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + function template(text, settings, oldSettings) { + console.error("should not happen"); } - function isReserved(token) { - if (!token.reserved) { - return false; + // Traverses the children of `obj` along `path`. If a child is a function, it + // is invoked with its parent as context. Returns the value of the final + // child, or `fallback` if any child is undefined. + function result(obj, path, fallback) { + path = toPath(path); + var length = path.length; + if (!length) { + return isFunction$1(fallback) ? fallback.call(obj) : fallback; } - var meta = token.meta; - - if (meta && meta.isFutureReservedWord && state.inES5()) { - // ES3 FutureReservedWord in an ES5 environment. - if (!meta.es5) { - return false; - } - - // Some ES5 FutureReservedWord identifiers are active only - // within a strict mode environment. - if (meta.strictOnly) { - if (!state.option.strict && !state.isStrict()) { - return false; - } - } - - if (token.isProperty) { - return false; + for (var i = 0; i < length; i++) { + var prop = obj == null ? void 0 : obj[path[i]]; + if (prop === void 0) { + prop = fallback; + i = length; // Ensure we don't continue iterating. } + obj = isFunction$1(prop) ? prop.call(obj) : prop; } + return obj; + } - return true; + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + function uniqueId(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; } - function supplant(str, data) { - return str.replace(/\{([^{}]*)\}/g, function(a, b) { - var r = data[b]; - return typeof r === "string" || typeof r === "number" ? r : a; - }); + // Start chaining a wrapped Underscore object. + function chain(obj) { + var instance = _$1(obj); + instance._chain = true; + return instance; } - function combine(dest, src) { - Object.keys(src).forEach(function(name) { - if (_.has(JSHINT.blacklist, name)) return; - dest[name] = src[name]; - }); + // Internal function to execute `sourceFunc` bound to `context` with optional + // `args`. Determines whether to execute a function as a constructor or as a + // normal function. + function executeBound(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (isObject(result)) return result; + return self; } - function processenforceall() { - if (state.option.enforceall) { - for (var enforceopt in options.bool.enforcing) { - if (state.option[enforceopt] === undefined && - !options.noenforceall[enforceopt]) { - state.option[enforceopt] = true; - } - } - for (var relaxopt in options.bool.relaxing) { - if (state.option[relaxopt] === undefined) { - state.option[relaxopt] = false; + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. `_` acts + // as a placeholder by default, allowing any combination of arguments to be + // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. + var partial = restArguments(function(func, boundArgs) { + var placeholder = partial.placeholder; + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }); + + partial.placeholder = _$1; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). + var bind = restArguments(function(func, context, args) { + if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function'); + var bound = restArguments(function(callArgs) { + return executeBound(func, bound, context, this, args.concat(callArgs)); + }); + return bound; + }); + + // Internal helper for collection methods to determine whether a collection + // should be iterated as an array or as an object. + // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var isArrayLike = createSizePropertyCheck(getLength); + + // Internal implementation of a recursive `flatten` function. + function flatten$1(input, depth, strict, output) { + output = output || []; + if (!depth && depth !== 0) { + depth = Infinity; + } else if (depth <= 0) { + return output.concat(input); + } + var idx = output.length; + for (var i = 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) { + // Flatten current level of array or arguments object. + if (depth > 1) { + flatten$1(value, depth - 1, strict, output); + idx = output.length; + } else { + var j = 0, len = value.length; + while (j < len) output[idx++] = value[j++]; } + } else if (!strict) { + output[idx++] = value; } } + return output; } - function assume() { - processenforceall(); + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + var bindAll = restArguments(function(obj, keys) { + keys = flatten$1(keys, false, false); + var index = keys.length; + if (index < 1) throw new Error('bindAll must be passed function names'); + while (index--) { + var key = keys[index]; + obj[key] = bind(obj[key], obj); + } + return obj; + }); - /** - * TODO: Remove in JSHint 3 - */ - if (!state.option.esversion && !state.option.moz) { - if (state.option.es3) { - state.option.esversion = 3; - } else if (state.option.esnext) { - state.option.esversion = 6; - } else { - state.option.esversion = 5; + // Memoize an expensive function by storing its results. + function memoize(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!has$1(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + } + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + var delay = restArguments(function(func, wait, args) { + return setTimeout(function() { + return func.apply(null, args); + }, wait); + }); + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + var defer = partial(delay, _$1, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + function throttle(func, wait, options) { + var timeout, context, args, result; + var previous = 0; + if (!options) options = {}; + + var later = function() { + previous = options.leading === false ? 0 : now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + + var throttled = function() { + var _now = now(); + if (!previous && options.leading === false) previous = _now; + var remaining = wait - (_now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = _now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); } - } + return result; + }; - if (state.inES5()) { - combine(predefined, vars.ecmaIdentifiers[5]); - } + throttled.cancel = function() { + clearTimeout(timeout); + previous = 0; + timeout = context = args = null; + }; - if (state.inES6()) { - combine(predefined, vars.ecmaIdentifiers[6]); - } + return throttled; + } - if (state.option.module) { - if (state.option.strict === true) { - state.option.strict = "global"; + // When a sequence of calls of the returned function ends, the argument + // function is triggered. The end of a sequence is defined by the `wait` + // parameter. If `immediate` is passed, the argument function will be + // triggered at the beginning of the sequence instead of at the end. + function debounce(func, wait, immediate) { + var timeout, previous, args, result, context; + + var later = function() { + var passed = now() - previous; + if (wait > passed) { + timeout = setTimeout(later, wait - passed); + } else { + timeout = null; + if (!immediate) result = func.apply(context, args); + // This check is needed because `func` can recursively invoke `debounced`. + if (!timeout) args = context = null; } - /** - * TODO: Extend this restriction to *all* ES6-specific options. - */ - if (!state.inES6()) { - warning("W134", state.tokens.next, "module", 6); + }; + + var debounced = restArguments(function(_args) { + context = this; + args = _args; + previous = now(); + if (!timeout) { + timeout = setTimeout(later, wait); + if (immediate) result = func.apply(context, args); } - } + return result; + }); - if (state.option.couch) { - combine(predefined, vars.couch); - } + debounced.cancel = function() { + clearTimeout(timeout); + timeout = args = context = null; + }; - if (state.option.qunit) { - combine(predefined, vars.qunit); - } + return debounced; + } - if (state.option.rhino) { - combine(predefined, vars.rhino); - } + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + function wrap(func, wrapper) { + return partial(wrapper, func); + } - if (state.option.shelljs) { - combine(predefined, vars.shelljs); - combine(predefined, vars.node); - } - if (state.option.typed) { - combine(predefined, vars.typed); - } + // Returns a negated version of the passed-in predicate. + function negate(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + } - if (state.option.phantom) { - combine(predefined, vars.phantom); - if (state.option.strict === true) { - state.option.strict = "global"; + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + function compose() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + } + + // Returns a function that will only be executed on and after the Nth call. + function after(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); } - } + }; + } - if (state.option.prototypejs) { - combine(predefined, vars.prototypejs); + // Returns a function that will only be executed up to (but not including) the + // Nth call. + function before(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + } + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + var once = partial(before, 2); + + // Returns the first key on an object that passes a truth test. + function findKey(obj, predicate, context) { + predicate = cb(predicate, context); + var _keys = keys(obj), key; + for (var i = 0, length = _keys.length; i < length; i++) { + key = _keys[i]; + if (predicate(obj[key], key, obj)) return key; } + } - if (state.option.node) { - combine(predefined, vars.node); - combine(predefined, vars.typed); - if (state.option.strict === true) { - state.option.strict = "global"; + // Internal function to generate `_.findIndex` and `_.findLastIndex`. + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; } - } + return -1; + }; + } - if (state.option.devel) { - combine(predefined, vars.devel); - } + // Returns the first index on an array-like that passes a truth test. + var findIndex = createPredicateIndexFinder(1); - if (state.option.dojo) { - combine(predefined, vars.dojo); - } + // Returns the last index on an array-like that passes a truth test. + var findLastIndex = createPredicateIndexFinder(-1); - if (state.option.browser) { - combine(predefined, vars.browser); - combine(predefined, vars.typed); + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + function sortedIndex(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; } + return low; + } - if (state.option.browserify) { - combine(predefined, vars.browser); - combine(predefined, vars.typed); - combine(predefined, vars.browserify); - if (state.option.strict === true) { - state.option.strict = "global"; + // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions. + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; } - } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), isNaN$1); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } - if (state.option.nonstandard) { - combine(predefined, vars.nonstandard); - } + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + var indexOf = createIndexFinder(1, findIndex, sortedIndex); + + // Return the position of the last occurrence of an item in an array, + // or -1 if the item is not included in the array. + var lastIndexOf = createIndexFinder(-1, findLastIndex); + + // Return the first value which passes a truth test. + function find(obj, predicate, context) { + var keyFinder = isArrayLike(obj) ? findIndex : findKey; + var key = keyFinder(obj, predicate, context); + if (key !== void 0 && key !== -1) return obj[key]; + } - if (state.option.jasmine) { - combine(predefined, vars.jasmine); - } + // Convenience version of a common use case of `_.find`: getting the first + // object containing specific `key:value` pairs. + function findWhere(obj, attrs) { + return find(obj, matcher(attrs)); + } - if (state.option.jquery) { - combine(predefined, vars.jquery); + // The cornerstone for collection functions, an `each` + // implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + function each(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var _keys = keys(obj); + for (i = 0, length = _keys.length; i < length; i++) { + iteratee(obj[_keys[i]], _keys[i], obj); + } } + return obj; + } - if (state.option.mootools) { - combine(predefined, vars.mootools); - } + // Return the results of applying the iteratee to each element. + function map(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var _keys = !isArrayLike(obj) && keys(obj), + length = (_keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = _keys ? _keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + } - if (state.option.worker) { - combine(predefined, vars.worker); - } + // Internal helper to create a reducing function, iterating left or right. + function createReduce(dir) { + // Wrap code that reassigns argument variables in a separate function than + // the one that accesses `arguments.length` to avoid a perf hit. (#1991) + var reducer = function(obj, iteratee, memo, initial) { + var _keys = !isArrayLike(obj) && keys(obj), + length = (_keys || obj).length, + index = dir > 0 ? 0 : length - 1; + if (!initial) { + memo = obj[_keys ? _keys[index] : index]; + index += dir; + } + for (; index >= 0 && index < length; index += dir) { + var currentKey = _keys ? _keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + }; - if (state.option.wsh) { - combine(predefined, vars.wsh); - } + return function(obj, iteratee, memo, context) { + var initial = arguments.length >= 3; + return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); + }; + } - if (state.option.globalstrict && state.option.strict !== false) { - state.option.strict = "global"; - } + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + var reduce = createReduce(1); - if (state.option.yui) { - combine(predefined, vars.yui); - } + // The right-associative version of reduce, also known as `foldr`. + var reduceRight = createReduce(-1); - if (state.option.mocha) { - combine(predefined, vars.mocha); - } + // Return all the elements that pass a truth test. + function filter(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; } - // Produce an error warning. - function quit(code, line, chr) { - var percentage = Math.floor((line / state.lines.length) * 100); - var message = messages.errors[code].desc; + // Return all the elements for which a truth test fails. + function reject(obj, predicate, context) { + return filter(obj, negate(cb(predicate)), context); + } - throw { - name: "JSHintError", - line: line, - character: chr, - message: message + " (" + percentage + "% scanned).", - raw: message, - code: code - }; + // Determine whether all of the elements pass a truth test. + function every(obj, predicate, context) { + predicate = cb(predicate, context); + var _keys = !isArrayLike(obj) && keys(obj), + length = (_keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = _keys ? _keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; } - function removeIgnoredMessages() { - var ignored = state.ignoredLines; + // Determine if at least one element in the object passes a truth test. + function some(obj, predicate, context) { + predicate = cb(predicate, context); + var _keys = !isArrayLike(obj) && keys(obj), + length = (_keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = _keys ? _keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + } - if (_.isEmpty(ignored)) return; - JSHINT.errors = _.reject(JSHINT.errors, function(err) { return ignored[err.line] }); + // Determine if the array or object contains a given item (using `===`). + function contains(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return indexOf(obj, item, fromIndex) >= 0; } - function warning(code, t, a, b, c, d) { - var ch, l, w, msg; + // Invoke a method (with arguments) on every item in a collection. + var invoke = restArguments(function(obj, path, args) { + var contextPath, func; + if (isFunction$1(path)) { + func = path; + } else { + path = toPath(path); + contextPath = path.slice(0, -1); + path = path[path.length - 1]; + } + return map(obj, function(context) { + var method = func; + if (!method) { + if (contextPath && contextPath.length) { + context = deepGet(context, contextPath); + } + if (context == null) return void 0; + method = context[path]; + } + return method == null ? method : method.apply(context, args); + }); + }); - if (/^W\d{3}$/.test(code)) { - if (state.ignored[code]) - return; + // Convenience version of a common use case of `_.map`: fetching a property. + function pluck(obj, key) { + return map(obj, property(key)); + } - msg = messages.warnings[code]; - } else if (/E\d{3}/.test(code)) { - msg = messages.errors[code]; - } else if (/I\d{3}/.test(code)) { - msg = messages.info[code]; + // Convenience version of a common use case of `_.filter`: selecting only + // objects containing specific `key:value` pairs. + function where(obj, attrs) { + return filter(obj, matcher(attrs)); + } + + // Return the maximum element (or element-based computation). + function max(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { + obj = isArrayLike(obj) ? obj : values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value != null && value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + each(obj, function(v, index, list) { + computed = iteratee(v, index, list); + if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) { + result = v; + lastComputed = computed; + } + }); } + return result; + } - t = t || state.tokens.next || {}; - if (t.id === "(end)") { // `~ - t = state.tokens.curr; + // Return the minimum element (or element-based computation). + function min(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { + obj = isArrayLike(obj) ? obj : values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value != null && value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + each(obj, function(v, index, list) { + computed = iteratee(v, index, list); + if (computed < lastComputed || (computed === Infinity && result === Infinity)) { + result = v; + lastComputed = computed; + } + }); } + return result; + } - l = t.line || 0; - ch = t.from || 0; + // Safely create a real, live array from anything iterable. + var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; + function toArray(obj) { + if (!obj) return []; + if (isArray(obj)) return slice.call(obj); + if (isString(obj)) { + // Keep surrogate pair characters together. + return obj.match(reStrSymbol); + } + if (isArrayLike(obj)) return map(obj, identity); + return values(obj); + } - w = { - id: "(error)", - raw: msg.desc, - code: msg.code, - evidence: state.lines[l - 1] || "", - line: l, - character: ch, - scope: JSHINT.scope, - a: a, - b: b, - c: c, - d: d + // Sample **n** random values from a collection using the modern version of the + // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `_.map`. + function sample(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = values(obj); + return obj[random(obj.length - 1)]; + } + var sample = toArray(obj); + var length = getLength(sample); + n = Math.max(Math.min(n, length), 0); + var last = length - 1; + for (var index = 0; index < n; index++) { + var rand = random(index, last); + var temp = sample[index]; + sample[index] = sample[rand]; + sample[rand] = temp; + } + return sample.slice(0, n); + } + + // Shuffle a collection. + function shuffle(obj) { + return sample(obj, Infinity); + } + + // Sort the object's values by a criterion produced by an iteratee. + function sortBy(obj, iteratee, context) { + var index = 0; + iteratee = cb(iteratee, context); + return pluck(map(obj, function(value, key, list) { + return { + value: value, + index: index++, + criteria: iteratee(value, key, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + } + + // An internal function used for aggregate "group by" operations. + function group(behavior, partition) { + return function(obj, iteratee, context) { + var result = partition ? [[], []] : {}; + iteratee = cb(iteratee, context); + each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; }; + } - w.reason = supplant(msg.desc, w); - JSHINT.errors.push(w); + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + var groupBy = group(function(result, value, key) { + if (has$1(result, key)) result[key].push(value); else result[key] = [value]; + }); - removeIgnoredMessages(); + // Indexes the object's values by a criterion, similar to `_.groupBy`, but for + // when you know that your index values will be unique. + var indexBy = group(function(result, value, key) { + result[key] = value; + }); - if (JSHINT.errors.length >= state.option.maxerr) - quit("E043", l, ch); + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + var countBy = group(function(result, value, key) { + if (has$1(result, key)) result[key]++; else result[key] = 1; + }); - return w; - } + // Split a collection into two arrays: one whose elements all pass the given + // truth test, and one whose elements all do not pass the truth test. + var partition = group(function(result, value, pass) { + result[pass ? 0 : 1].push(value); + }, true); - function warningAt(m, l, ch, a, b, c, d) { - return warning(m, { - line: l, - from: ch - }, a, b, c, d); + // Return the number of elements in a collection. + function size(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : keys(obj).length; } - function error(m, t, a, b, c, d) { - warning(m, t, a, b, c, d); + // Internal `_.pick` helper function to determine whether `key` is an enumerable + // property name of `obj`. + function keyInObj(value, key, obj) { + return key in obj; } - function errorAt(m, l, ch, a, b, c, d) { - return error(m, { - line: l, - from: ch - }, a, b, c, d); + // Return a copy of the object only containing the allowed properties. + var pick = restArguments(function(obj, keys) { + var result = {}, iteratee = keys[0]; + if (obj == null) return result; + if (isFunction$1(iteratee)) { + if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); + keys = allKeys(obj); + } else { + iteratee = keyInObj; + keys = flatten$1(keys, false, false); + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }); + + // Return a copy of the object without the disallowed properties. + var omit = restArguments(function(obj, keys) { + var iteratee = keys[0], context; + if (isFunction$1(iteratee)) { + iteratee = negate(iteratee); + if (keys.length > 1) context = keys[1]; + } else { + keys = map(flatten$1(keys, false, false), String); + iteratee = function(value, key) { + return !contains(keys, key); + }; + } + return pick(obj, iteratee, context); + }); + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + function initial(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); } - // Tracking of "internal" scripts, like eval containing a static string - function addInternalSrc(elem, src) { - var i; - i = { - id: "(internal)", - elem: elem, - value: src - }; - JSHINT.internals.push(i); - return i; + // Get the first element of an array. Passing **n** will return the first N + // values in the array. The **guard** check allows it to work with `_.map`. + function first(array, n, guard) { + if (array == null || array.length < 1) return n == null || guard ? void 0 : []; + if (n == null || guard) return array[0]; + return initial(array, array.length - n); } - function doOption() { - var nt = state.tokens.next; - var body = nt.body.match(/(-\s+)?[^\s,:]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g) || []; + // Returns everything but the first entry of the `array`. Especially useful on + // the `arguments` object. Passing an **n** will return the rest N values in the + // `array`. + function rest(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + } - var predef = {}; - if (nt.type === "globals") { - body.forEach(function(g, idx) { - g = g.split(":"); - var key = (g[0] || "").trim(); - var val = (g[1] || "").trim(); + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + function last(array, n, guard) { + if (array == null || array.length < 1) return n == null || guard ? void 0 : []; + if (n == null || guard) return array[array.length - 1]; + return rest(array, Math.max(0, array.length - n)); + } - if (key === "-" || !key.length) { - // Ignore trailing comma - if (idx > 0 && idx === body.length - 1) { - return; - } - error("E002", nt); - return; - } + // Trim out all falsy values from an array. + function compact(array) { + return filter(array, Boolean); + } - if (key.charAt(0) === "-") { - key = key.slice(1); - val = false; + // Flatten out an array, either recursively (by default), or up to `depth`. + // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively. + function flatten(array, depth) { + return flatten$1(array, depth, false); + } - JSHINT.blacklist[key] = key; - delete predefined[key]; - } else { - predef[key] = (val === "true"); - } - }); + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + var difference = restArguments(function(array, rest) { + rest = flatten$1(rest, true, true); + return filter(array, function(value){ + return !contains(rest, value); + }); + }); - combine(predefined, predef); + // Return a version of the array that does not contain the specified value(s). + var without = restArguments(function(array, otherArrays) { + return difference(array, otherArrays); + }); - for (var key in predef) { - if (_.has(predef, key)) { - declared[key] = nt; + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // The faster algorithm will not work with an iteratee if the iteratee + // is not a one-to-one function, so providing an iteratee will disable + // the faster algorithm. + function uniq(array, isSorted, iteratee, context) { + if (!isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted && !iteratee) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!contains(seen, computed)) { + seen.push(computed); + result.push(value); } + } else if (!contains(result, value)) { + result.push(value); } } + return result; + } - if (nt.type === "exported") { - body.forEach(function(e, idx) { - if (!e.length) { - // Ignore trailing comma - if (idx > 0 && idx === body.length - 1) { - return; - } - error("E002", nt); - return; - } + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + var union = restArguments(function(arrays) { + return uniq(flatten$1(arrays, true, true)); + }); - state.funct["(scope)"].addExported(e); - }); + // Produce an array that contains every item shared between all the + // passed-in arrays. + function intersection(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (contains(result, item)) continue; + var j; + for (j = 1; j < argsLength; j++) { + if (!contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); } + return result; + } - if (nt.type === "members") { - membersOnly = membersOnly || {}; + // Complement of zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices. + function unzip(array) { + var length = (array && max(array, getLength).length) || 0; + var result = Array(length); - body.forEach(function(m) { - var ch1 = m.charAt(0); - var ch2 = m.charAt(m.length - 1); + for (var index = 0; index < length; index++) { + result[index] = pluck(array, index); + } + return result; + } - if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) { - m = m - .substr(1, m.length - 2) - .replace("\\\"", "\""); - } + // Zip together multiple lists into a single array -- elements that share + // an index go together. + var zip = restArguments(unzip); + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. Passing by pairs is the reverse of `_.pairs`. + function object(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + } - membersOnly[m] = false; - }); + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](https://docs.python.org/library/functions.html#range). + function range(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + if (!step) { + step = stop < start ? -1 : 1; } - var numvals = [ - "maxstatements", - "maxparams", - "maxdepth", - "maxcomplexity", - "maxerr", - "maxlen", - "indent" - ]; + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); - if (nt.type === "jshint" || nt.type === "jslint") { - body.forEach(function(g) { - g = g.split(":"); - var key = (g[0] || "").trim(); - var val = (g[1] || "").trim(); + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } - if (!checkOption(key, nt)) { - return; - } + return range; + } - if (numvals.indexOf(key) >= 0) { - // GH988 - numeric options can be disabled by setting them to `false` - if (val !== "false") { - val = +val; + // Chunk a single array into multiple arrays, each containing `count` or fewer + // items. + function chunk(array, count) { + if (count == null || count < 1) return []; + var result = []; + var i = 0, length = array.length; + while (i < length) { + result.push(slice.call(array, i, i += count)); + } + return result; + } - if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) { - error("E032", nt, g[1].trim()); - return; - } + // Helper function to continue chaining intermediate results. + function chainResult(instance, obj) { + return instance._chain ? _$1(obj).chain() : obj; + } - state.option[key] = val; - } else { - state.option[key] = key === "indent" ? 4 : false; - } + // Add your own custom functions to the Underscore object. + function mixin(obj) { + each(functions(obj), function(name) { + var func = _$1[name] = obj[name]; + _$1.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return chainResult(this, func.apply(_$1, args)); + }; + }); + return _$1; + } - return; + // Add all mutator `Array` functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _$1.prototype[name] = function() { + var obj = this._wrapped; + if (obj != null) { + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) { + delete obj[0]; } + } + return chainResult(this, obj); + }; + }); - if (key === "validthis") { - // `validthis` is valid only within a function scope. - - if (state.funct["(global)"]) - return void error("E009"); + // Add all accessor `Array` functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _$1.prototype[name] = function() { + var obj = this._wrapped; + if (obj != null) obj = method.apply(obj, arguments); + return chainResult(this, obj); + }; + }); - if (val !== "true" && val !== "false") - return void error("E002", nt); + // Named Exports + + var allExports = { + __proto__: null, + VERSION: VERSION, + restArguments: restArguments, + isObject: isObject, + isNull: isNull, + isUndefined: isUndefined, + isBoolean: isBoolean, + isElement: isElement, + isString: isString, + isNumber: isNumber, + isDate: isDate, + isRegExp: isRegExp, + isError: isError, + isSymbol: isSymbol, + isArrayBuffer: isArrayBuffer, + isDataView: isDataView$1, + isArray: isArray, + isFunction: isFunction$1, + isArguments: isArguments$1, + isFinite: isFinite$1, + isNaN: isNaN$1, + isTypedArray: isTypedArray$1, + isEmpty: isEmpty, + isMatch: isMatch, + isEqual: isEqual, + isMap: isMap, + isWeakMap: isWeakMap, + isSet: isSet, + isWeakSet: isWeakSet, + keys: keys, + allKeys: allKeys, + values: values, + pairs: pairs, + invert: invert, + functions: functions, + methods: functions, + extend: extend, + extendOwn: extendOwn, + assign: extendOwn, + defaults: defaults, + create: create, + clone: clone, + tap: tap, + get: get, + has: has, + mapObject: mapObject, + identity: identity, + constant: constant, + noop: noop, + toPath: toPath$1, + property: property, + propertyOf: propertyOf, + matcher: matcher, + matches: matcher, + times: times, + random: random, + now: now, + escape: _escape, + unescape: _unescape, + templateSettings: templateSettings, + template: template, + result: result, + uniqueId: uniqueId, + chain: chain, + iteratee: iteratee, + partial: partial, + bind: bind, + bindAll: bindAll, + memoize: memoize, + delay: delay, + defer: defer, + throttle: throttle, + debounce: debounce, + wrap: wrap, + negate: negate, + compose: compose, + after: after, + before: before, + once: once, + findKey: findKey, + findIndex: findIndex, + findLastIndex: findLastIndex, + sortedIndex: sortedIndex, + indexOf: indexOf, + lastIndexOf: lastIndexOf, + find: find, + detect: find, + findWhere: findWhere, + each: each, + forEach: each, + map: map, + collect: map, + reduce: reduce, + foldl: reduce, + inject: reduce, + reduceRight: reduceRight, + foldr: reduceRight, + filter: filter, + select: filter, + reject: reject, + every: every, + all: every, + some: some, + any: some, + contains: contains, + includes: contains, + include: contains, + invoke: invoke, + pluck: pluck, + where: where, + max: max, + min: min, + shuffle: shuffle, + sample: sample, + sortBy: sortBy, + groupBy: groupBy, + indexBy: indexBy, + countBy: countBy, + partition: partition, + toArray: toArray, + size: size, + pick: pick, + omit: omit, + first: first, + head: first, + take: first, + initial: initial, + last: last, + rest: rest, + tail: rest, + drop: rest, + compact: compact, + flatten: flatten, + without: without, + uniq: uniq, + unique: uniq, + union: union, + intersection: intersection, + difference: difference, + unzip: unzip, + transpose: unzip, + zip: zip, + object: object, + range: range, + chunk: chunk, + mixin: mixin, + 'default': _$1 + }; - state.option.validthis = (val === "true"); - return; - } + // Default Export - if (key === "quotmark") { - switch (val) { - case "true": - case "false": - state.option.quotmark = (val === "true"); - break; - case "double": - case "single": - state.option.quotmark = val; - break; - default: - error("E002", nt); - } - return; - } + // Add all of the Underscore functions to the wrapper object. + var _ = mixin(allExports); + // Legacy Node.js API. + _._ = _; - if (key === "shadow") { - switch (val) { - case "true": - state.option.shadow = true; - break; - case "outer": - state.option.shadow = "outer"; - break; - case "false": - case "inner": - state.option.shadow = "inner"; - break; - default: - error("E002", nt); - } - return; - } + return _; - if (key === "unused") { - switch (val) { - case "true": - state.option.unused = true; - break; - case "false": - state.option.unused = false; - break; - case "vars": - case "strict": - state.option.unused = val; - break; - default: - error("E002", nt); - } - return; - } +}))); - if (key === "latedef") { - switch (val) { - case "true": - state.option.latedef = true; - break; - case "false": - state.option.latedef = false; - break; - case "nofunc": - state.option.latedef = "nofunc"; - break; - default: - error("E002", nt); - } - return; - } - if (key === "ignore") { - switch (val) { - case "line": - state.ignoredLines[nt.line] = true; - removeIgnoredMessages(); - break; - default: - error("E002", nt); - } - return; - } +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],"/../../../jshint/src/jshint.js":[function(_dereq_,module,exports){ +/*! + * JSHint, by JSHint Community. + * + * Licensed under the MIT license. + * + * JSHint is a derivative work of JSLint: + * + * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) + * + * 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: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * 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. + * + */ - if (key === "strict") { - switch (val) { - case "true": - state.option.strict = true; - break; - case "false": - state.option.strict = false; - break; - case "func": - case "global": - case "implied": - state.option.strict = val; - break; - default: - error("E002", nt); - } - return; - } +/*jshint quotmark:double */ +/*exported console */ - if (key === "module") { - /** - * TODO: Extend this restriction to *all* "environmental" options. - */ - if (!hasParsedCode(state.funct)) { - error("E055", state.tokens.next, "module"); - } - } +var _ = _dereq_("underscore"); +_.clone = _dereq_("lodash.clone"); +var events = _dereq_("events"); +var vars = _dereq_("./vars.js"); +var messages = _dereq_("./messages.js"); +var Lexer = _dereq_("./lex.js").Lexer; +var reg = _dereq_("./reg.js"); +var state = _dereq_("./state.js").state; +var style = _dereq_("./style.js"); +var options = _dereq_("./options.js"); +var scopeManager = _dereq_("./scope-manager.js"); +var prodParams = _dereq_("./prod-params.js"); - /** - * TODO: Remove in JSHint 3 - */ - var esversions = { - es3 : 3, - es5 : 5, - esnext: 6 - }; - if (_.has(esversions, key)) { - switch (val) { - case "true": - state.option.moz = false; - state.option.esversion = esversions[key]; - break; - case "false": - if (!state.option.moz) { - state.option.esversion = 5; - } - break; - default: - error("E002", nt); - } - return; - } +// We need this module here because environments such as IE and Rhino +// don't necessarilly expose the 'console' API and browserify uses +// it to log things. It's a sad state of affair, really. +var console = _dereq_("console-browserify"); - if (key === "esversion") { - switch (val) { - case "5": - if (state.inES5(true)) { - warning("I003"); - } - /* falls through */ - case "3": - case "6": - state.option.moz = false; - state.option.esversion = +val; - break; - case "2015": - state.option.moz = false; - state.option.esversion = 6; - break; - default: - error("E002", nt); - } - if (!hasParsedCode(state.funct)) { - error("E055", state.tokens.next, "esversion"); - } - return; - } +// We build the application inside a function so that we produce only a singleton +// variable. That function will be invoked immediately, and its return value is +// the JSHINT function itself. - var match = /^([+-])(W\d{3})$/g.exec(key); - if (match) { - // ignore for -W..., unignore for +W... - state.ignored[match[2]] = (match[1] === "-"); - return; - } +var JSHINT = (function() { + "use strict"; - var tn; - if (val === "true" || val === "false") { - if (nt.type === "jslint") { - tn = options.renamed[key] || key; - state.option[tn] = (val === "true"); + var api, // Extension API - if (options.inverted[tn] !== undefined) { - state.option[tn] = !state.option[tn]; - } - } else { - state.option[key] = (val === "true"); - } + // These are operators that should not be used with the ! operator. + bang = { + "<" : true, + "<=" : true, + "==" : true, + "===": true, + "!==": true, + "!=" : true, + ">" : true, + ">=" : true, + "+" : true, + "-" : true, + "*" : true, + "/" : true, + "%" : true + }, - if (key === "newcap") { - state.option["(explicitNewcap)"] = true; - } - return; - } + declared, // Globals that were declared using /*global ... */ syntax. - error("E002", nt); - }); + functions, // All of the functions - assume(); - } - } + inblock, + indent, + lookahead, + lex, + member, + membersOnly, + predefined, // Global variables defined by option - // We need a peek function. If it has an argument, it peeks that much farther - // ahead. It is used to distinguish - // for ( var i in ... - // from - // for ( var i = ... + extraModules = [], + emitter = new events.EventEmitter(); - function peek(p) { - var i = p || 0, j = lookahead.length, t; + function checkOption(name, isStable, t) { + var type, validNames; - if (i < j) { - return lookahead[i]; + if (isStable) { + type = ""; + validNames = options.validNames; + } else { + type = "unstable "; + validNames = options.unstableNames; } - while (j <= i) { - t = lookahead[j]; - if (!t) { - t = lookahead[j] = lex.token(); - } - j += 1; + name = name.trim(); + + if (/^[+-]W\d{3}$/g.test(name)) { + return true; } - // Peeking past the end of the program should produce the "(end)" token. - if (!t && state.tokens.next.id === "(end)") { - return state.tokens.next; + if (validNames.indexOf(name) === -1) { + if (t.type !== "jslint" && !_.has(options.removed, name)) { + error("E001", t, type, name); + return false; + } } - return t; + return true; } - function peekIgnoreEOL() { - var i = 0; - var t; - do { - t = peek(i++); - } while (t.id === "(endline)"); - return t; + function isString(obj) { + return Object.prototype.toString.call(obj) === "[object String]"; } - // Produce the next token. It looks for programming errors. + function isIdentifier(tkn, value) { + if (!tkn) + return false; - function advance(id, t) { + if (!tkn.identifier || tkn.value !== value) + return false; - switch (state.tokens.curr.id) { - case "(number)": - if (state.tokens.next.id === ".") { - warning("W005", state.tokens.curr); - } - break; - case "-": - if (state.tokens.next.id === "-" || state.tokens.next.id === "--") { - warning("W006"); - } - break; - case "+": - if (state.tokens.next.id === "+" || state.tokens.next.id === "++") { - warning("W007"); - } - break; + return true; + } + + /** + * ES3 defined a set of "FutureReservedWords" in order "to allow for the + * possibility of future adoption of [proposed] extensions." + * + * ES5 reduced the set of FutureReservedWords, in some cases by using them to + * define new syntactic forms (e.g. `class` and `const`) and in other cases + * by simply allowing their use as Identifiers (e.g. `int` and `goto`). + * Separately, ES5 introduced new restrictions on certain tokens, but limited + * the restriction to strict mode code (e.g. `let` and `yield`). + * + * This function determines if a given token describes a reserved word + * according to the current state of the parser. + * + * @param {number} context - the parsing context; see `prod-params.js` for + * more information + * @param {Token} token + */ + function isReserved(context, token) { + if (!token.reserved) { + return false; } + var meta = token.meta; - if (id && state.tokens.next.id !== id) { - if (t) { - if (state.tokens.next.id === "(end)") { - error("E019", t, t.id); - } else { - error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value); + if (meta && meta.isFutureReservedWord) { + if (state.inES5()) { + // ES3 FutureReservedWord in an ES5 environment. + if (!meta.es5) { + return false; + } + + if (token.isProperty) { + return false; } - } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) { - warning("W116", state.tokens.next, id, state.tokens.next.value); } + } else if (meta && meta.es5 && !state.inES5()) { + return false; } - state.tokens.prev = state.tokens.curr; - state.tokens.curr = state.tokens.next; - for (;;) { - state.tokens.next = lookahead.shift() || lex.token(); - - if (!state.tokens.next) { // No more tokens left, give up - quit("E041", state.tokens.curr.line); + // Some identifiers are reserved only within a strict mode environment. + if (meta && meta.strictOnly && state.inES5()) { + if (!state.option.strict && !state.isStrict()) { + return false; } + } - if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") { - return; - } + if (token.id === "await" && (!(context & prodParams.async) && !state.option.module)) { + return false; + } - if (state.tokens.next.check) { - state.tokens.next.check(); - } + if (token.id === "yield" && (!(context & prodParams.yield))) { + return state.isStrict(); + } - if (state.tokens.next.isSpecial) { - if (state.tokens.next.type === "falls through") { - state.tokens.curr.caseFallsThrough = true; - } else { - doOption(); + return true; + } + + function supplant(str, data) { + return str.replace(/\{([^{}]*)\}/g, function(a, b) { + var r = data[b]; + return typeof r === "string" || typeof r === "number" ? r : a; + }); + } + + function combine(dest, src) { + Object.keys(src).forEach(function(name) { + if (_.has(JSHINT.blacklist, name)) return; + dest[name] = src[name]; + }); + } + + function processenforceall() { + if (state.option.enforceall) { + for (var enforceopt in options.bool.enforcing) { + if (state.option[enforceopt] === undefined && + !options.noenforceall[enforceopt]) { + state.option[enforceopt] = true; } - } else { - if (state.tokens.next.id !== "(endline)") { - break; + } + for (var relaxopt in options.bool.relaxing) { + if (state.option[relaxopt] === undefined) { + state.option[relaxopt] = false; } } } } - function isInfix(token) { - return token.infix || (!token.identifier && !token.template && !!token.led); - } + /** + * Apply all linting options according to the status of the `state` object. + */ + function applyOptions() { + var badESOpt = null; + processenforceall(); - function isEndOfExpr() { - var curr = state.tokens.curr; - var next = state.tokens.next; - if (next.id === ";" || next.id === "}" || next.id === ":") { - return true; - } - if (isInfix(next) === isInfix(curr) || (curr.id === "yield" && state.inMoz())) { - return curr.line !== startLine(next); + /** + * TODO: Remove in JSHint 3 + */ + badESOpt = state.inferEsVersion(); + if (badESOpt) { + quit("E059", state.tokens.next, "esversion", badESOpt); } - return false; - } - - function isBeginOfExpr(prev) { - return !prev.left && prev.arity !== "unary"; - } - // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it - // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is - // like .nud except that it is only used on the first token of a statement. - // Having .fud makes it much easier to define statement-oriented languages like - // JavaScript. I retained Pratt's nomenclature. + if (state.inES5()) { + combine(predefined, vars.ecmaIdentifiers[5]); + } - // .nud Null denotation - // .fud First null denotation - // .led Left denotation - // lbp Left binding power - // rbp Right binding power + if (state.inES6()) { + combine(predefined, vars.ecmaIdentifiers[6]); + } - // They are elements of the parsing method called Top Down Operator Precedence. + if (state.inES8()) { + combine(predefined, vars.ecmaIdentifiers[8]); + } - function expression(rbp, initial) { - var left, isArray = false, isObject = false, isLetExpr = false; + if (state.inES11()) { + combine(predefined, vars.ecmaIdentifiers[11]); + } - state.nameStack.push(); + /** + * Use `in` to check for the presence of any explicitly-specified value for + * `globalstrict` because both `true` and `false` should trigger an error. + */ + if (state.option.strict === "global" && "globalstrict" in state.option) { + quit("E059", state.tokens.next, "strict", "globalstrict"); + } - // if current expression is a let expression - if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") { - if (!state.inMoz()) { - warning("W118", state.tokens.next, "let expressions"); + if (state.option.module) { + /** + * TODO: Extend this restriction to *all* ES6-specific options. + */ + if (!state.inES6()) { + warning("W134", state.tokens.next, "module", 6); } - isLetExpr = true; - // create a new block scope we use only for the current expression - state.funct["(scope)"].stack(); - advance("let"); - advance("("); - state.tokens.prev.fud(); - advance(")"); } - if (state.tokens.next.id === "(end)") - error("E006", state.tokens.curr); - - var isDangerous = - state.option.asi && - state.tokens.prev.line !== startLine(state.tokens.curr) && - _.contains(["]", ")"], state.tokens.prev.id) && - _.contains(["[", "("], state.tokens.curr.id); + if (state.option.regexpu) { + /** + * TODO: Extend this restriction to *all* ES6-specific options. + */ + if (!state.inES6()) { + warning("W134", state.tokens.next, "regexpu", 6); + } + } - if (isDangerous) - warning("W014", state.tokens.curr, state.tokens.curr.id); + if (state.option.couch) { + combine(predefined, vars.couch); + } - advance(); + if (state.option.qunit) { + combine(predefined, vars.qunit); + } - if (initial) { - state.funct["(verb)"] = state.tokens.curr.value; - state.tokens.curr.beginsStmt = true; + if (state.option.rhino) { + combine(predefined, vars.rhino); } - if (initial === true && state.tokens.curr.fud) { - left = state.tokens.curr.fud(); - } else { - if (state.tokens.curr.nud) { - left = state.tokens.curr.nud(); - } else { - error("E030", state.tokens.curr, state.tokens.curr.id); - } + if (state.option.shelljs) { + combine(predefined, vars.shelljs); + combine(predefined, vars.node); + } + if (state.option.typed) { + combine(predefined, vars.typed); + } - // TODO: use pratt mechanics rather than special casing template tokens - while ((rbp < state.tokens.next.lbp || state.tokens.next.type === "(template)") && - !isEndOfExpr()) { - isArray = state.tokens.curr.value === "Array"; - isObject = state.tokens.curr.value === "Object"; + if (state.option.phantom) { + combine(predefined, vars.phantom); + } - // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object() - // Line breaks in IfStatement heads exist to satisfy the checkJSHint - // "Line too long." error. - if (left && (left.value || (left.first && left.first.value))) { - // If the left.value is not "new", or the left.first.value is a "." - // then safely assume that this is not "new Array()" and possibly - // not "new Object()"... - if (left.value !== "new" || - (left.first && left.first.value && left.first.value === ".")) { - isArray = false; - // ...In the case of Object, if the left.value and state.tokens.curr.value - // are not equal, then safely assume that this not "new Object()" - if (left.value !== state.tokens.curr.value) { - isObject = false; - } - } - } + if (state.option.prototypejs) { + combine(predefined, vars.prototypejs); + } - advance(); + if (state.option.node) { + combine(predefined, vars.node); + combine(predefined, vars.typed); + } - if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { - warning("W009", state.tokens.curr); - } + if (state.option.devel) { + combine(predefined, vars.devel); + } - if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { - warning("W010", state.tokens.curr); - } + if (state.option.dojo) { + combine(predefined, vars.dojo); + } - if (left && state.tokens.curr.led) { - left = state.tokens.curr.led(left); - } else { - error("E033", state.tokens.curr, state.tokens.curr.id); - } - } + if (state.option.browser) { + combine(predefined, vars.browser); + combine(predefined, vars.typed); } - if (isLetExpr) { - state.funct["(scope)"].unstack(); + + if (state.option.browserify) { + combine(predefined, vars.browser); + combine(predefined, vars.typed); + combine(predefined, vars.browserify); } - state.nameStack.pop(); + if (state.option.nonstandard) { + combine(predefined, vars.nonstandard); + } - return left; - } + if (state.option.jasmine) { + combine(predefined, vars.jasmine); + } + if (state.option.jquery) { + combine(predefined, vars.jquery); + } - // Functions for conformance of style. + if (state.option.mootools) { + combine(predefined, vars.mootools); + } - function startLine(token) { - return token.startLine || token.line; - } + if (state.option.worker) { + combine(predefined, vars.worker); + } - function nobreaknonadjacent(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (!state.option.laxbreak && left.line !== startLine(right)) { - warning("W014", right, right.value); + if (state.option.wsh) { + combine(predefined, vars.wsh); } - } - function nolinebreak(t) { - t = t || state.tokens.curr; - if (t.line !== startLine(state.tokens.next)) { - warning("E022", t, t.value); + if (state.option.yui) { + combine(predefined, vars.yui); } - } - function nobreakcomma(left, right) { - if (left.line !== startLine(right)) { - if (!state.option.laxcomma) { - if (comma.first) { - warning("I001"); - comma.first = false; - } - warning("W014", left, right.value); - } + if (state.option.mocha) { + combine(predefined, vars.mocha); } } - function comma(opts) { - opts = opts || {}; - - if (!opts.peek) { - nobreakcomma(state.tokens.curr, state.tokens.next); - advance(","); - } else { - nobreakcomma(state.tokens.prev, state.tokens.curr); - } + // Produce an error warning. + function quit(code, token, a, b) { + var percentage = Math.floor((token.line / state.lines.length) * 100); + var message = messages.errors[code].desc; - if (state.tokens.next.identifier && !(opts.property && state.inES5())) { - // Keywords that cannot follow a comma operator. - switch (state.tokens.next.value) { - case "break": - case "case": - case "catch": - case "continue": - case "default": - case "do": - case "else": - case "finally": - case "for": - case "if": - case "in": - case "instanceof": - case "return": - case "switch": - case "throw": - case "try": - case "var": - case "let": - case "while": - case "with": - error("E024", state.tokens.next, state.tokens.next.value); - return false; - } - } + var exception = { + name: "JSHintError", + line: token.line, + character: token.from, + message: message + " (" + percentage + "% scanned).", + raw: message, + code: code, + a: a, + b: b + }; - if (state.tokens.next.type === "(punctuator)") { - switch (state.tokens.next.value) { - case "}": - case "]": - case ",": - if (opts.allowTrailing) { - return true; - } + exception.reason = supplant(message, exception) + " (" + percentage + + "% scanned)."; - /* falls through */ - case ")": - error("E024", state.tokens.next, state.tokens.next.value); - return false; - } - } - return true; + throw exception; } - // Functional constructors for making the symbols that will be inherited by - // tokens. - - function symbol(s, p) { - var x = state.syntax[s]; - if (!x || typeof x !== "object") { - state.syntax[s] = x = { - id: s, - lbp: p, - value: s - }; - } - return x; - } + function removeIgnoredMessages() { + var ignored = state.ignoredLines; - function delim(s) { - var x = symbol(s, 0); - x.delim = true; - return x; + if (_.isEmpty(ignored)) return; + JSHINT.errors = _.reject(JSHINT.errors, function(err) { return ignored[err.line] }); } - function stmt(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } + function warning(code, t, a, b, c, d) { + var ch, l, w, msg; - function blockstmt(s, f) { - var x = stmt(s, f); - x.block = true; - return x; - } + if (/^W\d{3}$/.test(code)) { + if (state.ignored[code]) + return; - function reserveName(x) { - var c = x.id.charAt(0); - if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) { - x.identifier = x.reserved = true; + msg = messages.warnings[code]; + } else if (/E\d{3}/.test(code)) { + msg = messages.errors[code]; + } else if (/I\d{3}/.test(code)) { + msg = messages.info[code]; } - return x; - } - function prefix(s, f) { - var x = symbol(s, 150); - reserveName(x); + t = t || state.tokens.next || {}; + if (t.id === "(end)") { // `~ + t = state.tokens.curr; + } - x.nud = (typeof f === "function") ? f : function() { - this.arity = "unary"; - this.right = expression(150); + l = t.line; + ch = t.from; - if (this.id === "++" || this.id === "--") { - if (state.option.plusplus) { - warning("W016", this, this.id); - } else if (this.right && (!this.right.identifier || isReserved(this.right)) && - this.right.id !== "." && this.right.id !== "[") { - warning("W017", this); - } + w = { + id: "(error)", + raw: msg.desc, + code: msg.code, + evidence: state.lines[l - 1] || "", + line: l, + character: ch, + scope: JSHINT.scope, + a: a, + b: b, + c: c, + d: d + }; - if (this.right && this.right.isMetaProperty) { - error("E031", this); - // detect increment/decrement of a const - // in the case of a.b, right will be the "." punctuator - } else if (this.right && this.right.identifier) { - state.funct["(scope)"].block.modify(this.right.value, this); - } - } + w.reason = supplant(msg.desc, w); + JSHINT.errors.push(w); - return this; - }; + removeIgnoredMessages(); - return x; + var errors = JSHINT.errors.filter(function(e) { return /E\d{3}/.test(e.code); }); + if (errors.length >= state.option.maxerr) { + quit("E043", t); + } + return w; } - function type(s, f) { - var x = delim(s); - x.type = s; - x.nud = f; - return x; + function warningAt(m, l, ch, a, b, c, d) { + return warning(m, { + line: l, + from: ch + }, a, b, c, d); } - function reserve(name, func) { - var x = type(name, func); - x.identifier = true; - x.reserved = true; - return x; + function error(m, t, a, b, c, d) { + warning(m, t, a, b, c, d); } - function FutureReservedWord(name, meta) { - var x = type(name, (meta && meta.nud) || function() { - return this; - }); - - meta = meta || {}; - meta.isFutureReservedWord = true; - - x.value = name; - x.identifier = true; - x.reserved = true; - x.meta = meta; - - return x; + function errorAt(m, l, ch, a, b, c, d) { + return error(m, { + line: l, + from: ch + }, a, b, c, d); } - function reservevar(s, v) { - return reserve(s, function() { - if (typeof v === "function") { - v(this); - } - return this; + // Tracking of "internal" scripts, like eval containing a static string + function addEvalCode(elem, token) { + JSHINT.internals.push({ + id: "(internal)", + elem: elem, + token: token, + code: token.value.replace(/([^\\])(\\*)\2\\n/g, "$1\n") }); } - function infix(s, f, p, w) { - var x = symbol(s, p); - reserveName(x); - x.infix = true; - x.led = function(left) { - if (!w) { - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - } - if ((s === "in" || s === "instanceof") && left.id === "!") { - warning("W018", left, "!"); - } - if (typeof f === "function") { - return f(left, this); - } else { - this.left = left; - this.right = expression(p); - return this; - } - }; - return x; - } + /** + * Process an inline linting directive + * + * @param {Token} directiveToken - the directive-bearing comment token + * @param {Token} previous - the token that preceeds the directive + */ + function lintingDirective(directiveToken, previous) { + var body = directiveToken.body.split(",") + .map(function(s) { return s.trim(); }); + var predef = {}; - function application(s) { - var x = symbol(s, 42); + if (directiveToken.type === "falls through") { + previous.caseFallsThrough = true; + return; + } - x.led = function(left) { - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + if (directiveToken.type === "globals") { + body.forEach(function(item, idx) { + var parts = item.split(":"); + var key = parts[0].trim(); - this.left = left; - this.right = doFunction({ type: "arrow", loneArg: left }); - return this; - }; - return x; - } + if (key === "-" || !key.length) { + // Ignore trailing comma + if (idx > 0 && idx === body.length - 1) { + return; + } + error("E002", directiveToken); + return; + } - function relation(s, f) { - var x = symbol(s, 100); + if (key.charAt(0) === "-") { + key = key.slice(1); - x.led = function(left) { - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - this.left = left; - var right = this.right = expression(100); + JSHINT.blacklist[key] = key; + delete predefined[key]; + } else { + predef[key] = parts.length > 1 && parts[1].trim() === "true"; + } + }); - if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) { - warning("W019", this); - } else if (f) { - f.apply(this, [left, right]); - } + combine(predefined, predef); - if (!left || !right) { - quit("E041", state.tokens.curr.line); + for (var key in predef) { + if (_.has(predef, key)) { + declared[key] = directiveToken; + } } + } - if (left.id === "!") { - warning("W018", left, "!"); - } + if (directiveToken.type === "exported") { + body.forEach(function(e, idx) { + if (!e.length) { + // Ignore trailing comma + if (idx > 0 && idx === body.length - 1) { + return; + } + error("E002", directiveToken); + return; + } - if (right.id === "!") { - warning("W018", right, "!"); - } + state.funct["(scope)"].addExported(e); + }); + } - return this; - }; - return x; - } - - function isPoorRelation(node) { - return node && - ((node.type === "(number)" && +node.value === 0) || - (node.type === "(string)" && node.value === "") || - (node.type === "null" && !state.option.eqnull) || - node.type === "true" || - node.type === "false" || - node.type === "undefined"); - } - - var typeofValues = {}; - typeofValues.legacy = [ - // E4X extended the `typeof` operator to return "xml" for the XML and - // XMLList types it introduced. - // Ref: 11.3.2 The typeof Operator - // http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-357.pdf - "xml", - // IE<9 reports "unknown" when the `typeof` operator is applied to an - // object existing across a COM+ bridge. In lieu of official documentation - // (which does not exist), see: - // http://robertnyman.com/2005/12/21/what-is-typeof-unknown/ - "unknown" - ]; - typeofValues.es3 = [ - "undefined", "boolean", "number", "string", "function", "object", - ]; - typeofValues.es3 = typeofValues.es3.concat(typeofValues.legacy); - typeofValues.es6 = typeofValues.es3.concat("symbol"); - - // Checks whether the 'typeof' operator is used with the correct - // value. For docs on 'typeof' see: - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof - function isTypoTypeof(left, right, state) { - var values; - - if (state.option.notypeof) - return false; - - if (!left || !right) - return false; - - values = state.inES6() ? typeofValues.es6 : typeofValues.es3; - - if (right.type === "(identifier)" && right.value === "typeof" && left.type === "(string)") - return !_.contains(values, left.value); - - return false; - } + if (directiveToken.type === "members") { + membersOnly = membersOnly || {}; - function isGlobalEval(left, state) { - var isGlobal = false; + body.forEach(function(m) { + var ch1 = m.charAt(0); + var ch2 = m.charAt(m.length - 1); - // permit methods to refer to an "eval" key in their own context - if (left.type === "this" && state.funct["(context)"] === null) { - isGlobal = true; - } - // permit use of "eval" members of objects - else if (left.type === "(identifier)") { - if (state.option.node && left.value === "global") { - isGlobal = true; - } + if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) { + m = m + .substr(1, m.length - 2) + .replace("\\\"", "\""); + } - else if (state.option.browser && (left.value === "window" || left.value === "document")) { - isGlobal = true; - } + membersOnly[m] = false; + }); } - return isGlobal; - } - - function findNativePrototype(left) { - var natives = [ - "Array", "ArrayBuffer", "Boolean", "Collator", "DataView", "Date", - "DateTimeFormat", "Error", "EvalError", "Float32Array", "Float64Array", - "Function", "Infinity", "Intl", "Int16Array", "Int32Array", "Int8Array", - "Iterator", "Number", "NumberFormat", "Object", "RangeError", - "ReferenceError", "RegExp", "StopIteration", "String", "SyntaxError", - "TypeError", "Uint16Array", "Uint32Array", "Uint8Array", "Uint8ClampedArray", - "URIError" + var numvals = [ + "maxstatements", + "maxparams", + "maxdepth", + "maxcomplexity", + "maxerr", + "maxlen", + "indent" ]; - function walkPrototype(obj) { - if (typeof obj !== "object") return; - return obj.right === "prototype" ? obj : walkPrototype(obj.left); - } + if (directiveToken.type === "jshint" || directiveToken.type === "jslint" || + directiveToken.type === "jshint.unstable") { + body.forEach(function(item) { + var parts = item.split(":"); + var key = parts[0].trim(); + var val = parts.length > 1 ? parts[1].trim() : ""; + var numberVal; - function walkNative(obj) { - while (!obj.identifier && typeof obj.left === "object") - obj = obj.left; + if (!checkOption(key, directiveToken.type !== "jshint.unstable", directiveToken)) { + return; + } - if (obj.identifier && natives.indexOf(obj.value) >= 0) - return obj.value; - } + if (numvals.indexOf(key) >= 0) { + // GH988 - numeric options can be disabled by setting them to `false` + if (val !== "false") { + numberVal = +val; - var prototype = walkPrototype(left); - if (prototype) return walkNative(prototype); - } + if (typeof numberVal !== "number" || !isFinite(numberVal) || + numberVal <= 0 || Math.floor(numberVal) !== numberVal) { + error("E032", directiveToken, val); + return; + } - /** - * Checks the left hand side of an assignment for issues, returns if ok - * @param {token} left - the left hand side of the assignment - * @param {token=} assignToken - the token for the assignment, used for reporting - * @param {object=} options - optional object - * @param {boolean} options.allowDestructuring - whether to allow destructuting binding - * @returns {boolean} Whether the left hand side is OK - */ - function checkLeftSideAssign(left, assignToken, options) { + state.option[key] = numberVal; + } else { + state.option[key] = key === "indent" ? 4 : false; + } - var allowDestructuring = options && options.allowDestructuring; + return; + } - assignToken = assignToken || left; + if (key === "validthis") { + // `validthis` is valid only within a function scope. - if (state.option.freeze) { - var nativeObject = findNativePrototype(left); - if (nativeObject) - warning("W121", left, nativeObject); - } + if (state.funct["(global)"]) + return void error("E009"); - if (left.identifier && !left.isMetaProperty) { - // reassign also calls modify - // but we are specific in order to catch function re-assignment - // and globals re-assignment - state.funct["(scope)"].block.reassign(left.value, left); - } + if (val !== "true" && val !== "false") + return void error("E002", directiveToken); - if (left.id === ".") { - if (!left.left || left.left.value === "arguments" && !state.isStrict()) { - warning("E031", assignToken); - } + state.option.validthis = (val === "true"); + return; + } - state.nameStack.set(state.tokens.prev); - return true; - } else if (left.id === "{" || left.id === "[") { - if (allowDestructuring && state.tokens.curr.left.destructAssign) { - state.tokens.curr.left.destructAssign.forEach(function(t) { - if (t.id) { - state.funct["(scope)"].block.modify(t.id, t.token); + if (key === "quotmark") { + switch (val) { + case "true": + case "false": + state.option.quotmark = (val === "true"); + break; + case "double": + case "single": + state.option.quotmark = val; + break; + default: + error("E002", directiveToken); } - }); - } else { - if (left.id === "{" || !left.left) { - warning("E031", assignToken); - } else if (left.left.value === "arguments" && !state.isStrict()) { - warning("E031", assignToken); + return; } - } - - if (left.id === "[") { - state.nameStack.set(left.right); - } - return true; - } else if (left.isMetaProperty) { - error("E031", assignToken); - return true; - } else if (left.identifier && !isReserved(left)) { - if (state.funct["(scope)"].labeltype(left.value) === "exception") { - warning("W022", left); - } - state.nameStack.set(left); - return true; - } - - if (left === state.syntax["function"]) { - warning("W023", state.tokens.curr); - } + if (key === "shadow") { + switch (val) { + case "true": + state.option.shadow = true; + break; + case "outer": + state.option.shadow = "outer"; + break; + case "false": + case "inner": + state.option.shadow = "inner"; + break; + default: + error("E002", directiveToken); + } + return; + } - return false; - } + if (key === "unused") { + switch (val) { + case "true": + state.option.unused = true; + break; + case "false": + state.option.unused = false; + break; + case "vars": + case "strict": + state.option.unused = val; + break; + default: + error("E002", directiveToken); + } + return; + } - function assignop(s, f, p) { - var x = infix(s, typeof f === "function" ? f : function(left, that) { - that.left = left; + if (key === "latedef") { + switch (val) { + case "true": + state.option.latedef = true; + break; + case "false": + state.option.latedef = false; + break; + case "nofunc": + state.option.latedef = "nofunc"; + break; + default: + error("E002", directiveToken); + } + return; + } - if (left && checkLeftSideAssign(left, that, { allowDestructuring: true })) { - that.right = expression(10); - return that; - } + if (key === "ignore") { + switch (val) { + case "line": + state.ignoredLines[directiveToken.line] = true; + removeIgnoredMessages(); + break; + default: + error("E002", directiveToken); + } + return; + } - error("E031", that); - }, p); + if (key === "strict") { + switch (val) { + case "true": + state.option.strict = true; + break; + case "false": + state.option.strict = false; + break; + case "global": + case "implied": + state.option.strict = val; + break; + default: + error("E002", directiveToken); + } + return; + } - x.exps = true; - x.assign = true; - return x; - } + if (key === "module") { + /** + * TODO: Extend this restriction to *all* "environmental" options. + */ + if (!hasParsedCode(state.funct)) { + error("E055", directiveToken, "module"); + } + } + if (key === "esversion") { + switch (val) { + case "3": + case "5": + case "6": + case "7": + case "8": + case "9": + case "10": + case "11": + state.option.moz = false; + state.option.esversion = +val; + break; + case "2015": + case "2016": + case "2017": + case "2018": + case "2019": + case "2020": + state.option.moz = false; + // Translate specification publication year to version number. + state.option.esversion = +val - 2009; + break; + default: + error("E002", directiveToken); + } + if (!hasParsedCode(state.funct)) { + error("E055", directiveToken, "esversion"); + } + return; + } - function bitwise(s, f, p) { - var x = symbol(s, p); - reserveName(x); - x.led = (typeof f === "function") ? f : function(left) { - if (state.option.bitwise) { - warning("W016", this, this.id); - } - this.left = left; - this.right = expression(p); - return this; - }; - return x; - } - - function bitwiseassignop(s) { - return assignop(s, function(left, that) { - if (state.option.bitwise) { - warning("W016", that, that.id); - } + var match = /^([+-])(W\d{3})$/g.exec(key); + if (match) { + // ignore for -W..., unignore for +W... + state.ignored[match[2]] = (match[1] === "-"); + return; + } - if (left && checkLeftSideAssign(left, that)) { - that.right = expression(10); - return that; - } - error("E031", that); - }, 20); - } + var tn; + if (val === "true" || val === "false") { + if (directiveToken.type === "jslint") { + tn = options.renamed[key] || key; + state.option[tn] = (val === "true"); - function suffix(s) { - var x = symbol(s, 150); + if (options.inverted[tn] !== undefined) { + state.option[tn] = !state.option[tn]; + } + } else if (directiveToken.type === "jshint.unstable") { + /* istanbul ignore next */ + state.option.unstable[key] = (val === "true"); + } else { + state.option[key] = (val === "true"); + } - x.led = function(left) { - // this = suffix e.g. "++" punctuator - // left = symbol operated e.g. "a" identifier or "a.b" punctuator - if (state.option.plusplus) { - warning("W016", this, this.id); - } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") { - warning("W017", this); - } + return; + } - if (left.isMetaProperty) { - error("E031", this); - // detect increment/decrement of a const - // in the case of a.b, left will be the "." punctuator - } else if (left && left.identifier) { - state.funct["(scope)"].block.modify(left.value, left); - } + error("E002", directiveToken); + }); - this.left = left; - return this; - }; - return x; + applyOptions(); + } } - // fnparam means that this identifier is being defined as a function - // argument (see identifier()) - // prop means that this identifier is that of an object property - - function optionalidentifier(fnparam, prop, preserve) { - if (!state.tokens.next.identifier) { - return; - } + /** + * Return a token beyond the token available in `state.tokens.next`. If no + * such token exists, return the "(end)" token. This function is used to + * determine parsing strategies in cases where the value of the next token + * does not provide sufficient information, as is the case with `for` loops, + * e.g.: + * + * for ( var i in ... + * + * versus: + * + * for ( var i = ... + * + * @param {number} [p] - offset of desired token; defaults to 0 + * + * @returns {token} + */ + function peek(p) { + var i = p || 0, j = lookahead.length, t; - if (!preserve) { - advance(); + if (i < j) { + return lookahead[i]; } - var curr = state.tokens.curr; - var val = state.tokens.curr.value; + while (j <= i) { + t = lex.token(); - if (!isReserved(curr)) { - return val; - } + // When the lexer is exhausted, this function should produce the "(end)" + // token, even in cases where the requested token is beyond the end of + // the input stream. + if (!t) { + // If the lookahead buffer is empty, the expected "(end)" token was + // already emitted by the most recent invocation of `advance` and is + // available as the next token. + if (!lookahead.length) { + return state.tokens.next; + } - if (prop) { - if (state.inES5()) { - return val; + return lookahead[j - 1]; } - } - if (fnparam && val === "undefined") { - return val; + lookahead[j] = t; + j += 1; } - warning("W024", state.tokens.curr, state.tokens.curr.id); - return val; + return t; } - // fnparam means that this identifier is being defined as a function - // argument - // prop means that this identifier is that of an object property - function identifier(fnparam, prop) { - var i = optionalidentifier(fnparam, prop, false); - if (i) { - return i; - } + function peekIgnoreEOL() { + var i = 0; + var t; + do { + t = peek(i++); + } while (t.id === "(endline)"); + return t; + } - // parameter destructuring with rest operator - if (state.tokens.next.value === "...") { - if (!state.inES6(true)) { - warning("W119", state.tokens.next, "spread/rest operator", "6"); - } - advance(); + /** + * Consume the next token. + * + * @param {string} [expected] - the expected value of the next token's `id` + * property (in the case of punctuators) or + * `value` property (in the case of identifiers + * and literals); if unspecified, any token will + * be accepted + * @param {object} [relatedToken] - the token that informed the expected + * value, if any (for example: the opening + * brace when a closing brace is expected); + * used to produce more meaningful errors + */ + function advance(expected, relatedToken) { + var nextToken = state.tokens.next; - if (checkPunctuator(state.tokens.next, "...")) { - warning("E024", state.tokens.next, "..."); - while (checkPunctuator(state.tokens.next, "...")) { - advance(); + if (expected && nextToken.id !== expected) { + if (relatedToken) { + if (nextToken.id === "(end)") { + error("E019", relatedToken, relatedToken.id); + } else { + error("E020", nextToken, expected, relatedToken.id, + relatedToken.line, nextToken.value); } - } - - if (!state.tokens.next.identifier) { - warning("E024", state.tokens.curr, "..."); - return; - } - - return identifier(fnparam, prop); - } else { - error("E030", state.tokens.next, state.tokens.next.value); - - // The token should be consumed after a warning is issued so the parser - // can continue as though an identifier were found. The semicolon token - // should not be consumed in this way so that the parser interprets it as - // a statement delimeter; - if (state.tokens.next.id !== ";") { - advance(); + } else if (nextToken.type !== "(identifier)" || nextToken.value !== expected) { + error("E021", nextToken, expected, nextToken.value); } } - } - - function reachable(controlToken) { - var i = 0, t; - if (state.tokens.next.id !== ";" || controlToken.inBracelessBlock) { - return; - } + state.tokens.prev = state.tokens.curr; + state.tokens.curr = state.tokens.next; for (;;) { - do { - t = peek(i); - i += 1; - } while (t.id !== "(end)" && t.id === "(comment)"); + state.tokens.next = lookahead.shift() || lex.token(); - if (t.reach) { - return; + if (!state.tokens.next) { // No more tokens left, give up + quit("E041", state.tokens.curr); } - if (t.id !== "(endline)") { - if (t.id === "function") { - if (state.option.latedef === true) { - warning("W026", t); - } - break; - } - warning("W027", t, t.value, controlToken.value); - break; + if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") { + return; } - } - } - - function parseFinalSemicolon() { - if (state.tokens.next.id !== ";") { - // don't complain about unclosed templates / strings - if (state.tokens.next.isUnclosed) return advance(); - var sameLine = startLine(state.tokens.next) === state.tokens.curr.line && - state.tokens.next.id !== "(end)"; - var blockEnd = checkPunctuator(state.tokens.next, "}"); + if (state.tokens.next.check) { + state.tokens.next.check(); + } - if (sameLine && !blockEnd) { - errorAt("E058", state.tokens.curr.line, state.tokens.curr.character); - } else if (!state.option.asi) { - // If this is the last statement in a block that ends on - // the same line *and* option lastsemic is on, ignore the warning. - // Otherwise, complain about missing semicolon. - if ((blockEnd && !state.option.lastsemic) || !sameLine) { - warningAt("W033", state.tokens.curr.line, state.tokens.curr.character); + if (state.tokens.next.isSpecial) { + lintingDirective(state.tokens.next, state.tokens.curr); + } else { + if (state.tokens.next.id !== "(endline)") { + break; } } - } else { - advance(";"); } } - function statement() { - var i = indent, r, t = state.tokens.next, hasOwnScope = false; + /** + * Determine whether a given token is an operator. + * + * @param {token} token + * + * @returns {boolean} + */ + function isOperator(token) { + return token.first || token.right || token.left || token.id === "yield" || token.id === "await"; + } - if (t.id === ";") { - advance(";"); - return; + function isEndOfExpr(context, curr, next) { + if (arguments.length <= 1) { + curr = state.tokens.curr; + next = state.tokens.next; } - // Is this a labelled statement? - var res = isReserved(t); - - // We're being more tolerant here: if someone uses - // a FutureReservedWord as a label, we warn but proceed - // anyway. - - if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") { - warning("W024", t, t.id); - res = false; + if (next.id === "in" && context & prodParams.noin) { + return true; } - if (t.identifier && !res && peek().id === ":") { - advance(); - advance(":"); - - hasOwnScope = true; - state.funct["(scope)"].stack(); - state.funct["(scope)"].block.addBreakLabel(t.value, { token: state.tokens.curr }); - - if (!state.tokens.next.labelled && state.tokens.next.value !== "{") { - warning("W028", state.tokens.next, t.value, state.tokens.next.value); - } - - state.tokens.next.label = t.value; - t = state.tokens.next; + if (next.id === ";" || next.id === "}" || next.id === ":") { + return true; } - // Is it a lonely block? - - if (t.id === "{") { - // Is it a switch case block? - // - // switch (foo) { - // case bar: { <= here. - // ... - // } - // } - var iscase = (state.funct["(verb)"] === "case" && state.tokens.curr.value === ":"); - block(true, true, false, false, iscase); - return; + if (next.infix === curr.infix || + // Infix operators which follow `yield` should only be consumed as part + // of the current expression if allowed by the syntactic grammar. In + // effect, this prevents automatic semicolon insertion when `yield` is + // followed by a newline and a comma operator (without enabling it when + // `yield` is followed by a newline and a `[` token). + (curr.id === "yield" && curr.rbp < next.rbp)) { + return !sameLine(curr, next); } - // Parse the statement. - - r = expression(0, true); + return false; + } - if (r && !(r.identifier && r.value === "function") && - !(r.type === "(punctuator)" && r.left && - r.left.identifier && r.left.value === "function")) { - if (!state.isStrict() && - state.option.strict === "global") { - warning("E007"); - } - } + /** + * The `expression` function is the heart of JSHint's parsing behaior. It is + * based on the Pratt parser, but it extends that model with a `fud` method. + * Short for "first null denotation," it it similar to the `nud` ("null + * denotation") function, but it is only used on the first token of a + * statement. This simplifies usage in statement-oriented languages like + * JavaScript. + * + * .nud Null denotation + * .fud First null denotation + * .led Left denotation + * lbp Left binding power + * rbp Right binding power + * + * They are elements of the parsing method called Top Down Operator Precedence. + * + * In addition to parsing, this function applies a number of linting patterns. + * + * @param {number} context - the parsing context (a bitfield describing + * conditions of the current parsing operation + * which can influence how the next tokens are + * interpreted); see `prod-params.js` for more + * detail) + * @param {number} rbp - the right-binding power of the token to be consumed + */ + function expression(context, rbp) { + var left, isArray = false, isObject = false; + var initial = context & prodParams.initial; + var curr; - // Look for the final semicolon. + context &= ~prodParams.initial; - if (!t.block) { - if (!state.option.expr && (!r || !r.exps)) { - warning("W030", state.tokens.curr); - } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") { - warning("W031", t); - } - parseFinalSemicolon(); - } + state.nameStack.push(); + if (state.tokens.next.id === "(end)") + error("E006", state.tokens.curr); - // Restore the indentation. + advance(); - indent = i; - if (hasOwnScope) { - state.funct["(scope)"].unstack(); + if (initial) { + state.funct["(verb)"] = state.tokens.curr.value; + state.tokens.curr.beginsStmt = true; } - return r; - } + curr = state.tokens.curr; - function statements() { - var a = [], p; + if (initial && curr.fud && (!curr.useFud || curr.useFud(context))) { + left = state.tokens.curr.fud(context); + } else { + if (state.tokens.curr.nud) { + left = state.tokens.curr.nud(context, rbp); + } else { + error("E030", state.tokens.curr, state.tokens.curr.id); + } - while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") { - if (state.tokens.next.id === ";") { - p = peek(); + while (rbp < state.tokens.next.lbp && !isEndOfExpr(context)) { + isArray = state.tokens.curr.value === "Array"; + isObject = state.tokens.curr.value === "Object"; - if (!p || (p.id !== "(" && p.id !== "[")) { - warning("W032"); + // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object() + // Line breaks in IfStatement heads exist to satisfy the checkJSHint + // "Line too long." error. + if (left && (left.value || (left.first && left.first.value))) { + // If the left.value is not "new", or the left.first.value is a "." + // then safely assume that this is not "new Array()" and possibly + // not "new Object()"... + if (left.value !== "new" || + (left.first && left.first.value && left.first.value === ".")) { + isArray = false; + // ...In the case of Object, if the left.value and state.tokens.curr.value + // are not equal, then safely assume that this not "new Object()" + if (left.value !== state.tokens.curr.value) { + isObject = false; + } + } } - advance(";"); - } else { - a.push(statement()); + advance(); + + if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { + warning("W009", state.tokens.curr); + } + + if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { + warning("W010", state.tokens.curr); + } + + if (left && state.tokens.curr.led) { + left = state.tokens.curr.led(context, left); + } else { + error("E033", state.tokens.curr, state.tokens.curr.id); + } } } - return a; + + state.nameStack.pop(); + + return left; } - /* - * read all directives - * recognizes a simple form of asi, but always - * warns, if it is used + // Functions for conformance of style. + + function sameLine(first, second) { + return first.line === (second.startLine || second.line); + } + + function nobreaknonadjacent(left, right) { + if (!state.option.laxbreak && !sameLine(left, right)) { + warning("W014", right, right.value); + } + } + + function nolinebreak(t) { + if (!sameLine(t, state.tokens.next)) { + warning("E022", t, t.value); + } + } + + /** + * Validate the comma token in the "current" position of the token stream. + * + * @param {object} [opts] + * @param {boolean} [opts.property] - flag indicating whether the current + * comma token is situated directly within + * an object initializer + * @param {boolean} [opts.allowTrailing] - flag indicating whether the + * current comma token may appear + * directly before a delimiter + * + * @returns {boolean} flag indicating the validity of the current comma + * token; `false` if the token directly causes a syntax + * error, `true` otherwise */ - function directives() { - var i, p, pn; + function checkComma(opts) { + var prev = state.tokens.prev; + var curr = state.tokens.curr; + opts = opts || {}; - while (state.tokens.next.id === "(string)") { - p = peek(0); - if (p.id === "(endline)") { - i = 1; - do { - pn = peek(i++); - } while (pn.id === "(endline)"); - if (pn.id === ";") { - p = pn; - } else if (pn.value === "[" || pn.value === ".") { - // string -> [ | . is a valid production - break; - } else if (!state.option.asi || pn.value === "(") { - // string -> ( is not a valid production - warning("W033", state.tokens.next); + if (!sameLine(prev, curr)) { + if (!state.option.laxcomma) { + if (checkComma.first) { + warning("I001", curr); + checkComma.first = false; } - } else if (p.id === "." || p.id === "[") { - break; - } else if (p.id !== ";") { - warning("W033", p); + warning("W014", prev, curr.value); } + } - advance(); - var directive = state.tokens.curr.value; - if (state.directive[directive] || - (directive === "use strict" && state.option.strict === "implied")) { - warning("W034", state.tokens.curr, directive); + if (state.tokens.next.identifier && !(opts.property && state.inES5())) { + // Keywords that cannot follow a comma operator. + switch (state.tokens.next.value) { + case "break": + case "case": + case "catch": + case "continue": + case "default": + case "do": + case "else": + case "finally": + case "for": + case "if": + case "in": + case "instanceof": + case "return": + case "switch": + case "throw": + case "try": + case "var": + case "let": + case "while": + case "with": + error("E024", state.tokens.next, state.tokens.next.value); + return false; } + } - // there's no directive negation, so always set to true - state.directive[directive] = true; + if (state.tokens.next.type === "(punctuator)") { + switch (state.tokens.next.value) { + case "}": + case "]": + case ",": + case ")": + if (opts.allowTrailing) { + return true; + } - if (p.id === ";") { - advance(";"); + error("E024", state.tokens.next, state.tokens.next.value); + return false; } } + return true; + } - if (state.isStrict()) { - if (!state.option["(explicitNewcap)"]) { - state.option.newcap = true; - } - state.option.undef = true; + /** + * Factory function for creating "symbols"--objects that will be inherited by + * tokens. The objects created by this function are stored in a symbol table + * and set as the prototype of the tokens generated by the lexer. + * + * Note that this definition of "symbol" describes an implementation detail + * of JSHint and is not related to the ECMAScript value type introduced in + * ES2015. + * + * @param {string} s - the name of the token; for keywords (e.g. `void`) and + * delimiters (e.g.. `[`), this is the token's text + * representation; for literals (e.g. numbers) and other + * "special" tokens (e.g. the end-of-file marker) this is + * a parenthetical value + * @param {number} p - the left-binding power of the token as used by the + * Pratt parsing semantics + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function symbol(s, p) { + var x = state.syntax[s]; + if (!x || typeof x !== "object") { + state.syntax[s] = x = { + id: s, + lbp: p, + // Symbols that accept a right-hand side do so with a binding power + // that is commonly identical to their left-binding power. (This value + // is relevant when determining if the grouping operator is necessary + // to override the precedence of surrounding operators.) Because the + // exponentiation operator's left-binding power and right-binding power + // are distinct, the values must be encoded separately. + rbp: p, + value: s + }; } + return x; } - - /* - * Parses a single block. A block is a sequence of statements wrapped in - * braces. + /** + * Convenience function for defining delimiter symbols. * - * ordinary - true for everything but function bodies and try blocks. - * stmt - true if block can be a single statement (e.g. in if/for/while). - * isfunc - true if block is a function body - * isfatarrow - true if its a body of a fat arrow function - * iscase - true if block is a switch case block + * @param {string} s - the name of the symbol + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) */ - function block(ordinary, stmt, isfunc, isfatarrow, iscase) { - var a, - b = inblock, - old_indent = indent, - m, - t, - line, - d; - - inblock = ordinary; + function delim(s) { + var x = symbol(s, 0); + x.delim = true; + return x; + } - t = state.tokens.next; + /** + * Convenience function for defining statement-denoting symbols. + * + * @param {string} s - the name of the symbol + * @param {function} f - the first null denotation function for the symbol; + * see the `expression` function for more detail + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function stmt(s, f) { + var x = delim(s); + x.identifier = x.reserved = true; + x.fud = f; + return x; + } - var metrics = state.funct["(metrics)"]; - metrics.nestedBlockDepth += 1; - metrics.verifyMaxNestedBlockDepthPerFunction(); + /** + * Convenience function for defining block-statement-denoting symbols. + * + * A block-statement-denoting symbol is one like 'if' or 'for', which will be + * followed by a block and will not have to end with a semicolon. + * + * @param {string} s - the name of the symbol + * @param {function} - the first null denotation function for the symbol; see + * the `expression` function for more detail + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function blockstmt(s, f) { + var x = stmt(s, f); + x.block = true; + return x; + } + /** + * Denote a given JSHint symbol as an identifier and a reserved keyword. + * + * @param {object} - a JSHint symbol value + * + * @returns {object} - the provided object + */ + function reserveName(x) { + var c = x.id.charAt(0); + if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) { + x.identifier = x.reserved = true; + } + return x; + } - if (state.tokens.next.id === "{") { - advance("{"); + /** + * Convenience function for defining "prefix" symbols--operators that accept + * expressions as a right-hand side. + * + * @param {string} s - the name of the symbol + * @param {function} [f] - the first null denotation function for the symbol; + * see the `expression` function for more detail + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function prefix(s, f) { + var x = symbol(s, 150); + reserveName(x); - // create a new block scope - state.funct["(scope)"].stack(); + x.nud = (typeof f === "function") ? f : function(context) { + this.arity = "unary"; + this.right = expression(context, 150); - line = state.tokens.curr.line; - if (state.tokens.next.id !== "}") { - indent += state.option.indent; - while (!ordinary && state.tokens.next.from > indent) { - indent += state.option.indent; + if (this.id === "++" || this.id === "--") { + if (state.option.plusplus) { + warning("W016", this, this.id); } - if (isfunc) { - m = {}; - for (d in state.directive) { - if (_.has(state.directive, d)) { - m[d] = state.directive[d]; - } - } - directives(); - - if (state.option.strict && state.funct["(context)"]["(global)"]) { - if (!m["use strict"] && !state.isStrict()) { - warning("E007"); - } - } + if (this.right) { + checkLeftSideAssign(context, this.right, this); } - - a = statements(); - - metrics.statementCount += a.length; - - indent -= state.option.indent; } - advance("}", t); + return this; + }; - if (isfunc) { - state.funct["(scope)"].validateParams(); - if (m) { - state.directive = m; - } - } + return x; + } - state.funct["(scope)"].unstack(); + /** + * Convenience function for defining "type" symbols--those that describe + * literal values. + * + * @param {string} s - the name of the symbol + * @param {function} f - the first null denotation function for the symbol; + * see the `expression` function for more detail + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function type(s, f) { + var x = symbol(s, 0); + x.type = s; + x.nud = f; + return x; + } - indent = old_indent; - } else if (!ordinary) { - if (isfunc) { - state.funct["(scope)"].stack(); + /** + * Convenience function for defining JSHint symbols for reserved + * keywords--those that are restricted from use as bindings (and as property + * names in ECMAScript 3 environments). + * + * @param {string} s - the name of the symbol + * @param {function} func - the first null denotation function for the + * symbol; see the `expression` function for more + * detail + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function reserve(name, func) { + var x = type(name, func); + x.identifier = true; + x.reserved = true; + return x; + } - m = {}; - if (stmt && !isfatarrow && !state.inMoz()) { - error("W118", state.tokens.curr, "function closure expressions"); - } + /** + * Convenience function for defining JSHint symbols for keywords that are + * only reserved in some circumstances. + * + * @param {string} name - the name of the symbol + * @param {object} [meta] - a collection of optional arguments + * @param {function} [meta.nud] -the null denotation function for the symbol; + * see the `expression` function for more detail + * @param {boolean} [meta.es5] - `true` if the identifier is reserved + * in ECMAScript 5 or later + * @param {boolean} [meta.strictOnly] - `true` if the identifier is only + * reserved in strict mode code. + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function FutureReservedWord(name, meta) { + var x = type(name, state.syntax["(identifier)"].nud); - if (!stmt) { - for (d in state.directive) { - if (_.has(state.directive, d)) { - m[d] = state.directive[d]; - } - } - } - expression(10); + meta = meta || {}; + meta.isFutureReservedWord = true; - if (state.option.strict && state.funct["(context)"]["(global)"]) { - if (!m["use strict"] && !state.isStrict()) { - warning("E007"); - } - } + x.value = name; + x.identifier = true; + x.reserved = true; + x.meta = meta; - state.funct["(scope)"].unstack(); + return x; + } + + /** + * Convenience function for defining "infix" symbols--operators that require + * operands as both "land-hand side" and "right-hand side". + * + * @param {string} s - the name of the symbol + * @param {function} [f] - a function to be invoked that consumes the + * right-hand side of the operator + * @param {number} p - the left-binding power of the token as used by the + * Pratt parsing semantics + * @param {boolean} [w] - if `true` + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function infix(s, f, p, w) { + var x = symbol(s, p); + reserveName(x); + x.infix = true; + x.led = function(context, left) { + if (!w) { + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + } + if ((s === "in" || s === "instanceof") && left.id === "!") { + warning("W018", left, "!"); + } + if (typeof f === "function") { + return f(context, left, this); } else { - error("E021", state.tokens.next, "{", state.tokens.next.value); + this.left = left; + this.right = expression(context, p); + return this; } - } else { + }; + return x; + } - // check to avoid let declaration not within a block - // though is fine inside for loop initializer section - state.funct["(noblockscopedvar)"] = state.tokens.next.id !== "for"; - state.funct["(scope)"].stack(); + /** + * Convenience function for defining the `=>` token as used in arrow + * functions. + * + * @param {string} s - the name of the symbol + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function application(s) { + var x = symbol(s, 42); - if (!stmt || state.option.curly) { - warning("W116", state.tokens.next, "{", state.tokens.next.value); - } + x.infix = true; + x.led = function(context, left) { + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - state.tokens.next.inBracelessBlock = true; - indent += state.option.indent; - // test indentation only if statement is in new line - a = [statement()]; - indent -= state.option.indent; + this.left = left; + this.right = doFunction(context, { type: "arrow", loneArg: left }); + return this; + }; + return x; + } - state.funct["(scope)"].unstack(); - delete state.funct["(noblockscopedvar)"]; - } + /** + * Convenience function for defining JSHint symbols for relation operators. + * + * @param {string} s - the name of the symbol + * @param {function} [f] - a function to be invoked to enforce any additional + * linting rules. + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function relation(s, f) { + var x = symbol(s, 100); - // Don't clear and let it propagate out if it is "break", "return" or similar in switch case - switch (state.funct["(verb)"]) { - case "break": - case "continue": - case "return": - case "throw": - if (iscase) { - break; + x.infix = true; + x.led = function(context, left) { + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + this.left = left; + var right = this.right = expression(context, 100); + + if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) { + warning("W019", this); + } else if (f) { + f.apply(this, [context, left, right]); } - /* falls through */ - default: - state.funct["(verb)"] = null; - } + if (!left || !right) { + quit("E041", state.tokens.curr); + } - inblock = b; - if (ordinary && state.option.noempty && (!a || a.length === 0)) { - warning("W035", state.tokens.prev); - } - metrics.nestedBlockDepth -= 1; - return a; - } + if (left.id === "!") { + warning("W018", left, "!"); + } + if (right.id === "!") { + warning("W018", right, "!"); + } - function countMember(m) { - if (membersOnly && typeof membersOnly[m] !== "boolean") { - warning("W036", state.tokens.curr, m); - } - if (typeof member[m] === "number") { - member[m] += 1; - } else { - member[m] = 1; - } + return this; + }; + return x; } - // Build the syntax table by declaring the syntactic elements of the language. + /** + * Determine if a given token marks the beginning of a UnaryExpression. + * + * @param {object} token + * + * @returns {boolean} + */ + function beginsUnaryExpression(token) { + return token.arity === "unary" && token.id !== "++" && token.id !== "--"; + } - type("(number)", function() { - return this; - }); + var typeofValues = {}; + typeofValues.legacy = [ + // E4X extended the `typeof` operator to return "xml" for the XML and + // XMLList types it introduced. + // Ref: 11.3.2 The typeof Operator + // http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-357.pdf + "xml", + // IE<9 reports "unknown" when the `typeof` operator is applied to an + // object existing across a COM+ bridge. In lieu of official documentation + // (which does not exist), see: + // http://robertnyman.com/2005/12/21/what-is-typeof-unknown/ + "unknown" + ]; + typeofValues.es3 = [ + "undefined", "boolean", "number", "string", "function", "object", + ]; + typeofValues.es3 = typeofValues.es3.concat(typeofValues.legacy); + typeofValues.es6 = typeofValues.es3.concat("symbol", "bigint"); - type("(string)", function() { - return this; - }); + /** + * Validate comparisons between the result of a `typeof` expression and a + * string literal. + * + * @param {token} [left] - one of the values being compared + * @param {token} [right] - the other value being compared + * @param {object} state - the global state object (see `state.js`) + * + * @returns {boolean} - `false` if the second token describes a `typeof` + * expression and the first token is a string literal + * whose value is never returned by that operator; + * `true` otherwise + */ + function isTypoTypeof(left, right, state) { + var values; - state.syntax["(identifier)"] = { - type: "(identifier)", - lbp: 0, - identifier: true, + if (state.option.notypeof) + return false; - nud: function() { - var v = this.value; + if (!left || !right) + return false; - // If this identifier is the lone parameter to a shorthand "fat arrow" - // function definition, i.e. - // - // x => x; - // - // ...it should not be considered as a variable in the current scope. It - // will be added to the scope of the new function when the next token is - // parsed, so it can be safely ignored for now. - if (state.tokens.next.id === "=>") { - return this; - } + values = state.inES6() ? typeofValues.es6 : typeofValues.es3; - if (!state.funct["(comparray)"].check(v)) { - state.funct["(scope)"].block.use(v, state.tokens.curr); + if (right.type === "(identifier)" && right.value === "typeof" && left.type === "(string)") { + if (left.value === "bigint") { + if (!state.inES11()) { + warning("W119", left, "BigInt", "11"); + } + + return false; } - return this; - }, - led: function() { - error("E033", state.tokens.next, state.tokens.next.value); + return !_.includes(values, left.value); } - }; - - var baseTemplateSyntax = { - lbp: 0, - identifier: false, - template: true, - }; - state.syntax["(template)"] = _.extend({ - type: "(template)", - nud: doTemplateLiteral, - led: doTemplateLiteral, - noSubst: false - }, baseTemplateSyntax); - - state.syntax["(template middle)"] = _.extend({ - type: "(template middle)", - middle: true, - noSubst: false - }, baseTemplateSyntax); - state.syntax["(template tail)"] = _.extend({ - type: "(template tail)", - tail: true, - noSubst: false - }, baseTemplateSyntax); + return false; + } - state.syntax["(no subst template)"] = _.extend({ - type: "(template)", - nud: doTemplateLiteral, - led: doTemplateLiteral, - noSubst: true, - tail: true // mark as tail, since it's always the last component - }, baseTemplateSyntax); + /** + * Determine if a given token describes the built-in `eval` function. + * + * @param {token} left + * @param {object} state - the global state object (see `state.js`) + * + * @returns {boolean} + */ + function isGlobalEval(left, state) { + var isGlobal = false; - type("(regexp)", function() { - return this; - }); + // permit methods to refer to an "eval" key in their own context + if (left.type === "this" && state.funct["(context)"] === null) { + isGlobal = true; + } + // permit use of "eval" members of objects + else if (left.type === "(identifier)") { + if (state.option.node && left.value === "global") { + isGlobal = true; + } - // ECMAScript parser + else if (state.option.browser && (left.value === "window" || left.value === "document")) { + isGlobal = true; + } + } - delim("(endline)"); - delim("(begin)"); - delim("(end)").reach = true; - delim("(error)").reach = true; - delim("}").reach = true; - delim(")"); - delim("]"); - delim("\"").reach = true; - delim("'").reach = true; - delim(";"); - delim(":").reach = true; - delim("#"); + return isGlobal; + } - reserve("else"); - reserve("case").reach = true; - reserve("catch"); - reserve("default").reach = true; - reserve("finally"); - reservevar("arguments", function(x) { - if (state.isStrict() && state.funct["(global)"]) { - warning("E008", x); - } - }); - reservevar("eval"); - reservevar("false"); - reservevar("Infinity"); - reservevar("null"); - reservevar("this", function(x) { - if (state.isStrict() && !isMethod() && - !state.option.validthis && ((state.funct["(statement)"] && - state.funct["(name)"].charAt(0) > "Z") || state.funct["(global)"])) { - warning("W040", x); - } - }); - reservevar("true"); - reservevar("undefined"); - - assignop("=", "assign", 20); - assignop("+=", "assignadd", 20); - assignop("-=", "assignsub", 20); - assignop("*=", "assignmult", 20); - assignop("/=", "assigndiv", 20).nud = function() { - error("E014"); - }; - assignop("%=", "assignmod", 20); - - bitwiseassignop("&="); - bitwiseassignop("|="); - bitwiseassignop("^="); - bitwiseassignop("<<="); - bitwiseassignop(">>="); - bitwiseassignop(">>>="); - infix(",", function(left, that) { - var expr; - that.exprs = [left]; + /** + * Determine if a given token describes a property of a built-in object. + * + * @param {token} left + * + * @returns {boolean} + */ + function findNativePrototype(left) { + var natives = [ + "Array", "ArrayBuffer", "Boolean", "Collator", "DataView", "Date", + "DateTimeFormat", "Error", "EvalError", "Float32Array", "Float64Array", + "Function", "Infinity", "Intl", "Int16Array", "Int32Array", "Int8Array", + "Iterator", "Number", "NumberFormat", "Object", "RangeError", + "ReferenceError", "RegExp", "StopIteration", "String", "SyntaxError", + "TypeError", "Uint16Array", "Uint32Array", "Uint8Array", "Uint8ClampedArray", + "URIError" + ]; - if (state.option.nocomma) { - warning("W127"); + function walkPrototype(obj) { + if (typeof obj !== "object") return; + return obj.right === "prototype" ? obj : walkPrototype(obj.left); } - if (!comma({ peek: true })) { - return that; - } - while (true) { - if (!(expr = expression(10))) { - break; - } - that.exprs.push(expr); - if (state.tokens.next.value !== "," || !comma()) { - break; + function walkNative(obj) { + while (!obj.identifier && typeof obj.left === "object") + obj = obj.left; + + if (obj.identifier && natives.indexOf(obj.value) >= 0 && + state.funct["(scope)"].isPredefined(obj.value)) { + return obj.value; } } - return that; - }, 10, true); - infix("?", function(left, that) { - increaseComplexityCount(); - that.left = left; - that.right = expression(10); - advance(":"); - that["else"] = expression(10); - return that; - }, 30); + var prototype = walkPrototype(left); + if (prototype) return walkNative(prototype); + } - var orPrecendence = 40; - infix("||", function(left, that) { - increaseComplexityCount(); - that.left = left; - that.right = expression(orPrecendence); - return that; - }, orPrecendence); - infix("&&", "and", 50); - bitwise("|", "bitor", 70); - bitwise("^", "bitxor", 80); - bitwise("&", "bitand", 90); - relation("==", function(left, right) { - var eqnull = state.option.eqnull && - ((left && left.value) === "null" || (right && right.value) === "null"); + /** + * Determine if the given token is a valid assignment target; emit errors + * and/or warnings as appropriate + * + * @param {number} context - the parsing context; see `prod-params.js` for + * more information + * @param {token} left - the left hand side of the assignment + * @param {token=} assignToken - the token for the assignment, used for + * reporting + * @param {object=} options - optional object + * @param {boolean} options.allowDestructuring - whether to allow + * destructuring binding + * + * @returns {boolean} Whether the left hand side is OK + */ + function checkLeftSideAssign(context, left, assignToken, options) { - switch (true) { - case !eqnull && state.option.eqeqeq: - this.from = this.character; - warning("W116", this, "===", "=="); - break; - case isPoorRelation(left): - warning("W041", this, "===", left.value); - break; - case isPoorRelation(right): - warning("W041", this, "===", right.value); - break; - case isTypoTypeof(right, left, state): - warning("W122", this, right.value); - break; - case isTypoTypeof(left, right, state): - warning("W122", this, left.value); - break; - } + var allowDestructuring = options && options.allowDestructuring; - return this; - }); - relation("===", function(left, right) { - if (isTypoTypeof(right, left, state)) { - warning("W122", this, right.value); - } else if (isTypoTypeof(left, right, state)) { - warning("W122", this, left.value); - } - return this; - }); - relation("!=", function(left, right) { - var eqnull = state.option.eqnull && - ((left && left.value) === "null" || (right && right.value) === "null"); + assignToken = assignToken || left; - if (!eqnull && state.option.eqeqeq) { - this.from = this.character; - warning("W116", this, "!==", "!="); - } else if (isPoorRelation(left)) { - warning("W041", this, "!==", left.value); - } else if (isPoorRelation(right)) { - warning("W041", this, "!==", right.value); - } else if (isTypoTypeof(right, left, state)) { - warning("W122", this, right.value); - } else if (isTypoTypeof(left, right, state)) { - warning("W122", this, left.value); - } - return this; - }); - relation("!==", function(left, right) { - if (isTypoTypeof(right, left, state)) { - warning("W122", this, right.value); - } else if (isTypoTypeof(left, right, state)) { - warning("W122", this, left.value); + if (state.option.freeze) { + var nativeObject = findNativePrototype(left); + if (nativeObject) + warning("W121", left, nativeObject); } - return this; - }); - relation("<"); - relation(">"); - relation("<="); - relation(">="); - bitwise("<<", "shiftleft", 120); - bitwise(">>", "shiftright", 120); - bitwise(">>>", "shiftrightunsigned", 120); - infix("in", "in", 120); - infix("instanceof", "instanceof", 120); - infix("+", function(left, that) { - var right; - that.left = left; - that.right = right = expression(130); - if (left && right && left.id === "(string)" && right.id === "(string)") { - left.value += right.value; - left.character = right.character; - if (!state.option.scripturl && reg.javascriptURL.test(left.value)) { - warning("W050", left); - } - return left; + if (left.identifier && !left.isMetaProperty) { + // The `reassign` method also calls `modify`, but we are specific in + // order to catch function re-assignment and globals re-assignment + state.funct["(scope)"].block.reassign(left.value, left); } - return that; - }, 130); - prefix("+", "num"); - prefix("+++", function() { - warning("W007"); - this.arity = "unary"; - this.right = expression(150); - return this; - }); - infix("+++", function(left) { - warning("W007"); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix("-", "sub", 130); - prefix("-", "neg"); - prefix("---", function() { - warning("W006"); - this.arity = "unary"; - this.right = expression(150); - return this; - }); - infix("---", function(left) { - warning("W006"); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix("*", "mult", 140); - infix("/", "div", 140); - infix("%", "mod", 140); - - suffix("++"); - prefix("++", "preinc"); - state.syntax["++"].exps = true; + if (left.id === ".") { + if (!left.left || left.left.value === "arguments" && !state.isStrict()) { + warning("W143", assignToken); + } - suffix("--"); - prefix("--", "predec"); - state.syntax["--"].exps = true; - prefix("delete", function() { - var p = expression(10); - if (!p) { - return this; - } + state.nameStack.set(state.tokens.prev); + return true; + } else if (left.id === "{" || left.id === "[") { + if (!allowDestructuring || !left.destructAssign) { + if (left.id === "{" || !left.left) { + warning("E031", assignToken); + } else if (left.left.value === "arguments" && !state.isStrict()) { + warning("W143", assignToken); + } + } - if (p.id !== "." && p.id !== "[") { - warning("W051"); - } - this.first = p; + if (left.id === "[") { + state.nameStack.set(left.right); + } - // The `delete` operator accepts unresolvable references when not in strict - // mode, so the operand may be undefined. - if (p.identifier && !state.isStrict()) { - p.forgiveUndef = true; - } - return this; - }).exps = true; + return true; + } else if (left.identifier && !isReserved(context, left) && !left.isMetaProperty) { + if (state.funct["(scope)"].bindingtype(left.value) === "exception") { + warning("W022", left); + } - prefix("~", function() { - if (state.option.bitwise) { - warning("W016", this, "~"); + if (left.value === "eval" && state.isStrict()) { + error("E031", assignToken); + return false; + } else if (left.value === "arguments") { + if (!state.isStrict()) { + warning("W143", assignToken); + } else { + error("E031", assignToken); + return false; + } + } + state.nameStack.set(left); + return true; } - this.arity = "unary"; - this.right = expression(150); - return this; - }); - prefix("...", function() { - if (!state.inES6(true)) { - warning("W119", this, "spread/rest operator", "6"); - } + error("E031", assignToken); - // TODO: Allow all AssignmentExpression - // once parsing permits. - // - // How to handle eg. number, boolean when the built-in - // prototype of may have an @@iterator definition? - // - // Number.prototype[Symbol.iterator] = function * () { - // yield this.valueOf(); - // }; - // - // var a = [ ...1 ]; - // console.log(a); // [1]; - // - // for (let n of [...10]) { - // console.log(n); - // } - // // 10 - // - // - // Boolean.prototype[Symbol.iterator] = function * () { - // yield this.valueOf(); - // }; - // - // var a = [ ...true ]; - // console.log(a); // [true]; - // - // for (let n of [...false]) { - // console.log(n); - // } - // // false - // - if (!state.tokens.next.identifier && - state.tokens.next.type !== "(string)" && - !checkPunctuators(state.tokens.next, ["[", "("])) { + return false; + } - error("E030", state.tokens.next, state.tokens.next.value); - } - expression(150); - return this; - }); + /** + * Convenience function for defining JSHint symbols for assignment operators. + * + * @param {string} s - the name of the symbol + * @param {function} [f] - a function to be invoked that consumes the + * right-hand side of the operator (see the `infix` + * function) + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function assignop(s, f) { + var x = infix(s, typeof f === "function" ? f : function(context, left, that) { + that.left = left; - prefix("!", function() { - this.arity = "unary"; - this.right = expression(150); + checkLeftSideAssign(context, left, that, { allowDestructuring: true }); - if (!this.right) { // '!' followed by nothing? Give up. - quit("E041", this.line || 0); - } + that.right = expression(context, 10); - if (bang[this.right.id] === true) { - warning("W018", this, "!"); - } - return this; - }); + return that; + }, 20); - prefix("typeof", (function() { - var p = expression(150); - this.first = this.right = p; + x.exps = true; + x.assign = true; - if (!p) { // 'typeof' followed by nothing? Give up. - quit("E041", this.line || 0, this.character || 0); - } + return x; + } - // The `typeof` operator accepts unresolvable references, so the operand - // may be undefined. - if (p.identifier) { - p.forgiveUndef = true; - } - return this; - })); - prefix("new", function() { - var mp = metaProperty("target", function() { - if (!state.inES6(true)) { - warning("W119", state.tokens.prev, "new.target", "6"); - } - var inFunction, c = state.funct; - while (c) { - inFunction = !c["(global)"]; - if (!c["(arrow)"]) { break; } - c = c["(context)"]; - } - if (!inFunction) { - warning("W136", state.tokens.prev, "new.target"); + /** + * Convenience function for defining JSHint symbols for bitwise operators. + * + * @param {string} s - the name of the symbol + * @param {function} [f] - the left denotation function for the symbol; see + * the `expression` function for more detail + * @param {number} p - the left-binding power of the token as used by the + * Pratt parsing semantics + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function bitwise(s, f, p) { + var x = symbol(s, p); + reserveName(x); + x.infix = true; + x.led = (typeof f === "function") ? f : function(context, left) { + if (state.option.bitwise) { + warning("W016", this, this.id); } - }); - if (mp) { return mp; } + this.left = left; + this.right = expression(context, p); + return this; + }; + return x; + } - var c = expression(155), i; - if (c && c.id !== "function") { - if (c.identifier) { - c["new"] = true; - switch (c.value) { - case "Number": - case "String": - case "Boolean": - case "Math": - case "JSON": - warning("W053", state.tokens.prev, c.value); - break; - case "Symbol": - if (state.inES6()) { - warning("W053", state.tokens.prev, c.value); - } - break; - case "Function": - if (!state.option.evil) { - warning("W054"); - } - break; - case "Date": - case "RegExp": - case "this": - break; - default: - if (c.id !== "function") { - i = c.value.substr(0, 1); - if (state.option.newcap && (i < "A" || i > "Z") && - !state.funct["(scope)"].isPredefined(c.value)) { - warning("W055", state.tokens.curr); - } - } - } - } else { - if (c.id !== "." && c.id !== "[" && c.id !== "(") { - warning("W056", state.tokens.curr); - } + /** + * Convenience function for defining JSHint symbols for bitwise assignment + * operators. See the `assignop` function for more detail. + * + * @param {string} s - the name of the symbol + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function bitwiseassignop(s) { + symbol(s, 20).exps = true; + return infix(s, function(context, left, that) { + if (state.option.bitwise) { + warning("W016", that, that.id); } - } else { - if (!state.option.supernew) - warning("W057", this); - } - if (state.tokens.next.id !== "(" && !state.option.supernew) { - warning("W058", state.tokens.curr, state.tokens.curr.value); - } - this.first = this.right = c; - return this; - }); - state.syntax["new"].exps = true; - prefix("void").exps = true; + checkLeftSideAssign(context, left, that); - infix(".", function(left, that) { - var m = identifier(false, true); + that.right = expression(context, 10); - if (typeof m === "string") { - countMember(m); - } + return that; + }, 20); + } - that.left = left; - that.right = m; + /** + * Convenience function for defining JSHint symbols for those operators which + * have a single operand that appears before them in the source code. + * + * @param {string} s - the name of the symbol + * + * @returns {object} - the object describing the JSHint symbol (provided to + * support cases where further refinement is necessary) + */ + function suffix(s) { + var x = symbol(s, 150); - if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") { - warning("W001"); - } + x.led = function(context, left) { + // this = suffix e.g. "++" punctuator + // left = symbol operated e.g. "a" identifier or "a.b" punctuator + if (state.option.plusplus) { + warning("W016", this, this.id); + } - if (left && left.value === "arguments" && (m === "callee" || m === "caller")) { - if (state.option.noarg) - warning("W059", left, m); - else if (state.isStrict()) - error("E008"); - } else if (!state.option.evil && left && left.value === "document" && - (m === "write" || m === "writeln")) { - warning("W060", left); + checkLeftSideAssign(context, left, this); + + this.left = left; + return this; + }; + return x; + } + + /** + * Retrieve the value of the next token if it is an identifier and optionally + * advance the parser. + * + * @param {number} context - the parsing context; see `prod-params.js` for + * more information + * @param {boolean} [isName] - `true` if an IdentifierName should be consumed + * (e.g. object properties) + * @param {boolean} [preserve] - `true` if the token should not be consumed + * + * @returns {string|undefined} - the value of the identifier, if present + */ + function optionalidentifier(context, isName, preserve) { + if (!state.tokens.next.identifier) { + return; } - if (!state.option.evil && (m === "eval" || m === "execScript")) { - if (isGlobalEval(left, state)) { - warning("W061"); - } + if (!preserve) { + advance(); } - return that; - }, 160, true); + var curr = state.tokens.curr; - infix("(", function(left, that) { - if (state.option.immed && left && !left.immed && left.id === "function") { - warning("W062"); + if (isReserved(context, curr) && !(isName && state.inES5())) { + warning("W024", state.tokens.curr, state.tokens.curr.id); } - var n = 0; - var p = []; + return curr.value; + } - if (left) { - if (left.type === "(identifier)") { - if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if ("Array Number String Boolean Date Object Error Symbol".indexOf(left.value) === -1) { - if (left.value === "Math") { - warning("W063", left); - } else if (state.option.newcap) { - warning("W064", left); - } - } - } - } + /** + * Consume the "..." token which designates "spread" and "rest" operations if + * it is present. If the operator is repeated, consume every repetition, and + * issue a single error describing the syntax error. + * + * @param {string} operation - either "spread" or "rest" + * + * @returns {boolean} a value describing whether or not any tokens were + * consumed in this way + */ + function spreadrest(operation) { + if (!checkPunctuator(state.tokens.next, "...")) { + return false; } - if (state.tokens.next.id !== ")") { - for (;;) { - p[p.length] = expression(10); - n += 1; - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } + if (!state.inES6(true)) { + warning("W119", state.tokens.next, operation + " operator", "6"); } + advance(); - advance(")"); - - if (typeof left === "object") { - if (!state.inES5() && left.value === "parseInt" && n === 1) { - warning("W065", state.tokens.curr); - } - if (!state.option.evil) { - if (left.value === "eval" || left.value === "Function" || - left.value === "execScript") { - warning("W061", left); - - if (p[0] && [0].id === "(string)") { - addInternalSrc(left, p[0].value); - } - } else if (p[0] && p[0].id === "(string)" && - (left.value === "setTimeout" || - left.value === "setInterval")) { - warning("W066", left); - addInternalSrc(left, p[0].value); - - // window.setTimeout/setInterval - } else if (p[0] && p[0].id === "(string)" && - left.value === "." && - left.left.value === "window" && - (left.right === "setTimeout" || - left.right === "setInterval")) { - warning("W066", left); - addInternalSrc(left, p[0].value); - } - } - if (!left.identifier && left.id !== "." && left.id !== "[" && left.id !== "=>" && - left.id !== "(" && left.id !== "&&" && left.id !== "||" && left.id !== "?" && - !(state.inES6() && left["(name)"])) { - warning("W067", that); + if (checkPunctuator(state.tokens.next, "...")) { + warning("E024", state.tokens.next, "..."); + while (checkPunctuator(state.tokens.next, "...")) { + advance(); } } - that.left = left; - return that; - }, 155, true).exps = true; - - prefix("(", function() { - var pn = state.tokens.next, pn1, i = -1; - var ret, triggerFnExpr, first, last; - var parens = 1; - var opening = state.tokens.curr; - var preceeding = state.tokens.prev; - var isNecessary = !state.option.singleGroups; + return true; + } - do { - if (pn.value === "(") { - parens += 1; - } else if (pn.value === ")") { - parens -= 1; - } + /** + * Ensure that the current token is an identifier and retrieve its value. + * + * @param {number} context - the parsing context; see `prod-params.js` for + * more information + * @param {boolean} [isName] - `true` if an IdentifierName should be consumed + * (e.g. object properties) + * + * @returns {string|undefined} - the value of the identifier, if present + */ + function identifier(context, isName) { + var i = optionalidentifier(context, isName, false); + if (i) { + return i; + } - i += 1; - pn1 = pn; - pn = peek(i); - } while (!(parens === 0 && pn1.value === ")") && pn.value !== ";" && pn.type !== "(end)"); + error("E030", state.tokens.next, state.tokens.next.value); - if (state.tokens.next.id === "function") { - triggerFnExpr = state.tokens.next.immed = true; + // The token should be consumed after a warning is issued so the parser + // can continue as though an identifier were found. The semicolon token + // should not be consumed in this way so that the parser interprets it as + // a statement delimiter; + if (state.tokens.next.id !== ";") { + advance(); } + } - // If the balanced grouping operator is followed by a "fat arrow", the - // current token marks the beginning of a "fat arrow" function and parsing - // should proceed accordingly. - if (pn.value === "=>") { - return doFunction({ type: "arrow", parsedOpening: true }); - } - var exprs = []; + /** + * Determine if the provided token may be evaluated and emit a linting + * warning if this is note the case. + * + * @param {token} controlToken + */ + function reachable(controlToken) { + var i = 0, t; + if (state.tokens.next.id !== ";" || controlToken.inBracelessBlock) { + return; + } + for (;;) { + do { + t = peek(i); + i += 1; + } while (t.id !== "(end)" && t.id === "(comment)"); - if (state.tokens.next.id !== ")") { - for (;;) { - exprs.push(expression(10)); + if (t.reach) { + return; + } - if (state.tokens.next.id !== ",") { + if (t.id !== "(endline)") { + if (isFunction(t, i)) { + if (state.option.latedef === true) { + warning("W026", t); + } break; } - if (state.option.nocomma) { - warning("W127"); - } - - comma(); + warning("W027", t, t.value, controlToken.value); + break; } } - advance(")", this); - if (state.option.immed && exprs[0] && exprs[0].id === "function") { - if (state.tokens.next.id !== "(" && - state.tokens.next.id !== "." && state.tokens.next.id !== "[") { - warning("W068", this); + function isFunction(t, i) { + if (t.id === "function") { + return true; + } + if (t.id === "async") { + t = peek(i); + return t.id === "function"; } } + } - if (!exprs.length) { - return; - } - if (exprs.length > 1) { - ret = Object.create(state.syntax[","]); - ret.exprs = exprs; - - first = exprs[0]; - last = exprs[exprs.length - 1]; - - if (!isNecessary) { - isNecessary = preceeding.assign || preceeding.delim; - } - } else { - ret = first = last = exprs[0]; + /** + * Consume the semicolon that delimits the statement currently being parsed, + * emitting relevant warnings/errors as appropriate. + * + * @param {token} stmt - token describing the statement under consideration + */ + function parseFinalSemicolon(stmt) { + if (state.tokens.next.id !== ";") { + // don't complain about unclosed templates / strings + if (state.tokens.next.isUnclosed) return advance(); - if (!isNecessary) { - isNecessary = - // Used to distinguish from an ExpressionStatement which may not - // begin with the `{` and `function` tokens - (opening.beginsStmt && (ret.id === "{" || triggerFnExpr || isFunctor(ret))) || - // Used to signal that a function expression is being supplied to - // some other operator. - (triggerFnExpr && - // For parenthesis wrapping a function expression to be considered - // necessary, the grouping operator should be the left-hand-side of - // some other operator--either within the parenthesis or directly - // following them. - (!isEndOfExpr() || state.tokens.prev.id !== "}")) || - // Used to demarcate an arrow function as the left-hand side of some - // operator. - (isFunctor(ret) && !isEndOfExpr()) || - // Used as the return value of a single-statement arrow function - (ret.id === "{" && preceeding.id === "=>") || - // Used to delineate an integer number literal from a dereferencing - // punctuator (otherwise interpreted as a decimal point) - (ret.type === "(number)" && - checkPunctuator(pn, ".") && /^\d+$/.test(ret.value)); + var isSameLine = sameLine(state.tokens.curr, state.tokens.next) && + state.tokens.next.id !== "(end)"; + var blockEnd = checkPunctuator(state.tokens.next, "}"); + + if (isSameLine && !blockEnd && !(stmt.id === "do" && state.inES6(true))) { + errorAt("E058", state.tokens.curr.line, state.tokens.curr.character); + } else if (!state.option.asi) { + + // If this is the last statement in a block that ends on the same line + // *and* option lastsemic is on, ignore the warning. Otherwise, issue + // a warning about missing semicolon. + if (!(blockEnd && isSameLine && state.option.lastsemic)) { + warningAt("W033", state.tokens.curr.line, state.tokens.curr.character); + } } + } else { + advance(";"); } + } - if (ret) { - // The operator may be necessary to override the default binding power of - // neighboring operators (whenever there is an operator in use within the - // first expression *or* the current group contains multiple expressions) - if (!isNecessary && (first.left || first.right || ret.exprs)) { - isNecessary = - (!isBeginOfExpr(preceeding) && first.lbp <= preceeding.lbp) || - (!isEndOfExpr() && last.lbp < state.tokens.next.lbp); - } + /** + * Consume a statement. + * + * @param {number} context - the parsing context; see `prod-params.js` for + * more information + * + * @returns {token} - the token describing the statement + */ + function statement(context) { + var i = indent, r, t = state.tokens.next, hasOwnScope = false; - if (!isNecessary) { - warning("W126", opening); - } + context |= prodParams.initial; - ret.paren = true; + if (t.id === ";") { + advance(";"); + return; } - return ret; - }); + // Is this a labelled statement? + var res = isReserved(context, t); - application("=>"); + // We're being more tolerant here: if someone uses + // a FutureReservedWord (that is not meant to start a statement) + // as a label, we warn but proceed anyway. - infix("[", function(left, that) { - var e = expression(10), s; - if (e && e.type === "(string)") { - if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) { - if (isGlobalEval(left, state)) { - warning("W061"); - } - } + if (res && t.meta && t.meta.isFutureReservedWord && !t.fud) { + warning("W024", t, t.id); + res = false; + } - countMember(e.value); - if (!state.option.sub && reg.identifier.test(e.value)) { - s = state.syntax[e.value]; - if (!s || !isReserved(s)) { - warning("W069", state.tokens.prev, e.value); - } + if (t.identifier && !res && peek().id === ":") { + advance(); + advance(":"); + + hasOwnScope = true; + state.funct["(scope)"].stack(); + state.funct["(scope)"].block.addLabel(t.value, { token: state.tokens.curr }); + + if (!state.tokens.next.labelled && state.tokens.next.value !== "{") { + warning("W028", state.tokens.next, t.value, state.tokens.next.value); } - } - advance("]", that); - if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") { - warning("W001"); + t = state.tokens.next; } - that.left = left; - that.right = e; - return that; - }, 160, true); + // Is it a lonely block? - function comprehensiveArrayExpression() { - var res = {}; - res.exps = true; - state.funct["(comparray)"].stack(); + if (t.id === "{") { + // Is it a switch case block? + // + // switch (foo) { + // case bar: { <= here. + // ... + // } + // } + var iscase = (state.funct["(verb)"] === "case" && state.tokens.curr.value === ":"); + block(context, true, true, false, false, iscase); - // Handle reversed for expressions, used in spidermonkey - var reversed = false; - if (state.tokens.next.value !== "for") { - reversed = true; - if (!state.inMoz()) { - warning("W116", state.tokens.next, "for", state.tokens.next.value); + if (hasOwnScope) { + state.funct["(scope)"].unstack(); } - state.funct["(comparray)"].setState("use"); - res.right = expression(10); - } - advance("for"); - if (state.tokens.next.value === "each") { - advance("each"); - if (!state.inMoz()) { - warning("W118", state.tokens.curr, "for each"); - } - } - advance("("); - state.funct["(comparray)"].setState("define"); - res.left = expression(130); - if (_.contains(["in", "of"], state.tokens.next.value)) { - advance(); - } else { - error("E045", state.tokens.curr); + return; } - state.funct["(comparray)"].setState("generate"); - expression(10); - advance(")"); - if (state.tokens.next.value === "if") { - advance("if"); - advance("("); - state.funct["(comparray)"].setState("filter"); - res.filter = expression(10); - advance(")"); - } + // Parse the statement. - if (!reversed) { - state.funct["(comparray)"].setState("use"); - res.right = expression(10); + r = expression(context, 0); + + if (r && !(r.identifier && r.value === "function") && + !(r.type === "(punctuator)" && r.left && + r.left.identifier && r.left.value === "function")) { + if (!state.isStrict() && state.stmtMissingStrict()) { + warning("E007"); + } } - advance("]"); - state.funct["(comparray)"].unstack(); - return res; - } + // Look for the final semicolon. - prefix("[", function() { - var blocktype = lookupBlockType(); - if (blocktype.isCompArray) { - if (!state.option.esnext && !state.inMoz()) { - warning("W118", state.tokens.curr, "array comprehension"); + if (!t.block) { + if (!state.option.expr && (!r || !r.exps)) { + warning("W030", state.tokens.curr); + } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") { + warning("W031", t); } - return comprehensiveArrayExpression(); - } else if (blocktype.isDestAssign) { - this.destructAssign = destructuringPattern({ openingParsed: true, assignment: true }); - return this; + + parseFinalSemicolon(t); } - var b = state.tokens.curr.line !== startLine(state.tokens.next); - this.first = []; - if (b) { - indent += state.option.indent; - if (state.tokens.next.from === indent + state.option.indent) { - indent += state.option.indent; - } + + + // Restore the indentation. + + indent = i; + if (hasOwnScope) { + state.funct["(scope)"].unstack(); } - while (state.tokens.next.id !== "(end)") { - while (state.tokens.next.id === ",") { - if (!state.option.elision) { - if (!state.inES5()) { - // Maintain compat with old options --- ES5 mode without - // elision=true will warn once per comma - warning("W070"); - } else { - warning("W128"); - do { - advance(","); - } while (state.tokens.next.id === ","); - continue; - } - } - advance(","); - } + return r; + } - if (state.tokens.next.id === "]") { - break; - } + /** + * Consume a series of statements until encountering either the end of the + * program or a token that interrupts control flow. + * + * @param {number} context - the parsing context; see `prod-params.js` for + * more information + * + * @returns {Array} - the tokens consumed + */ + function statements(context) { + var a = [], p; - this.first.push(expression(10)); - if (state.tokens.next.id === ",") { - comma({ allowTrailing: true }); - if (state.tokens.next.id === "]" && !state.inES5()) { - warning("W070", state.tokens.curr); - break; + while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") { + if (state.tokens.next.id === ";") { + p = peek(); + + if (!p || (p.id !== "(" && p.id !== "[")) { + warning("W032"); } + + advance(";"); } else { - break; + a.push(statement(context)); } } - if (b) { - indent -= state.option.indent; - } - advance("]", this); - return this; - }); - - - function isMethod() { - return state.funct["(statement)"] && state.funct["(statement)"].type === "class" || - state.funct["(context)"] && state.funct["(context)"]["(verb)"] === "class"; + return a; } - function isPropertyName(token) { - return token.identifier || token.id === "(string)" || token.id === "(number)"; - } - + /** + * Parse any directives in a directive prologue. + */ + function directives() { + var current = state.tokens.next; + while (state.tokens.next.id === "(string)") { + var next = peekIgnoreEOL(); + if (!isEndOfExpr(0, current, next)) { + break; + } + current = next; - function propertyName(preserveOrToken) { - var id; - var preserve = true; - if (typeof preserveOrToken === "object") { - id = preserveOrToken; - } else { - preserve = preserveOrToken; - id = optionalidentifier(false, true, preserve); - } + advance(); + var directive = state.tokens.curr.value; + if (state.directive[directive] || + (directive === "use strict" && state.option.strict === "implied")) { + warning("W034", state.tokens.curr, directive); + } - if (!id) { - if (state.tokens.next.id === "(string)") { - id = state.tokens.next.value; - if (!preserve) { - advance(); - } - } else if (state.tokens.next.id === "(number)") { - id = state.tokens.next.value.toString(); - if (!preserve) { - advance(); - } + // From ECMAScript 2016: + // + // > 14.1.2 Static Semantics: Early Errors + // > + // > [...] + // > - It is a Syntax Error if ContainsUseStrict of FunctionBody is true + // > and IsSimpleParameterList of FormalParameters is false. + if (directive === "use strict" && state.inES7() && + !state.funct["(global)"] && state.funct["(hasSimpleParams)"] === false) { + error("E065", state.tokens.curr); } - } else if (typeof id === "object") { - if (id.id === "(string)" || id.id === "(identifier)") id = id.value; - else if (id.id === "(number)") id = id.value.toString(); - } - if (id === "hasOwnProperty") { - warning("W001"); + state.directive[directive] = state.tokens.curr; + + parseFinalSemicolon(current); } - return id; + if (state.isStrict()) { + state.option.undef = true; + } } /** - * @param {Object} [options] - * @param {token} [options.loneArg] The argument to the function in cases - * where it was defined using the - * single-argument shorthand. - * @param {bool} [options.parsedOpening] Whether the opening parenthesis has - * already been parsed. - * @returns {{ arity: number, params: Array.}} - */ - function functionparams(options) { - var next; - var paramsIds = []; - var ident; - var tokens = []; - var t; - var pastDefault = false; - var pastRest = false; - var arity = 0; - var loneArg = options && options.loneArg; + * Parses a single block. A block is a sequence of statements wrapped in + * braces. + * + * @param {number} context - parsing context + * @param {boolean} ordinary - `true` for everything but function bodies and + * try blocks + * @param {boolean} [stmt] - `true` if block can be a single statement (e.g. + * in if/for/while) + * @param {boolean} [isfunc] - `true` if block is a function body + * @param {boolean} [isfatarrow] - `true` if its a body of a fat arrow + * function + * @param {boolean} [iscase] - `true` if block is a switch case block + * + * @returns {token} - the token describing the block + */ + function block(context, ordinary, stmt, isfunc, isfatarrow, iscase) { + var a, + b = inblock, + old_indent = indent, + m, + t, + d; - if (loneArg && loneArg.identifier === true) { - state.funct["(scope)"].addParam(loneArg.value, loneArg); - return { arity: 1, params: [ loneArg.value ] }; - } + inblock = ordinary; - next = state.tokens.next; + t = state.tokens.next; - if (!options || !options.parsedOpening) { - advance("("); - } + var metrics = state.funct["(metrics)"]; + metrics.nestedBlockDepth += 1; + metrics.verifyMaxNestedBlockDepthPerFunction(); - if (state.tokens.next.id === ")") { - advance(")"); - return; - } + if (state.tokens.next.id === "{") { + advance("{"); - function addParam(addParamArgs) { - state.funct["(scope)"].addParam.apply(state.funct["(scope)"], addParamArgs); - } + // create a new block scope + state.funct["(scope)"].stack(); - for (;;) { - arity++; - // are added to the param scope - var currentParams = []; + if (state.tokens.next.id !== "}") { + indent += state.option.indent; + while (!ordinary && state.tokens.next.from > indent) { + indent += state.option.indent; + } - if (_.contains(["{", "["], state.tokens.next.id)) { - tokens = destructuringPattern(); - for (t in tokens) { - t = tokens[t]; - if (t.id) { - paramsIds.push(t.id); - currentParams.push([t.id, t.token]); + if (isfunc) { + m = {}; + for (d in state.directive) { + m[d] = state.directive[d]; + } + directives(); + + state.funct["(isStrict)"] = state.isStrict(); + + if (state.option.strict && state.funct["(context)"]["(global)"]) { + if (!m["use strict"] && !state.isStrict()) { + warning("E007"); + } } } - } else { - if (checkPunctuator(state.tokens.next, "...")) pastRest = true; - ident = identifier(true); - if (ident) { - paramsIds.push(ident); - currentParams.push([ident, state.tokens.curr]); - } else { - // Skip invalid parameter. - while (!checkPunctuators(state.tokens.next, [",", ")"])) advance(); - } + + a = statements(context); + + metrics.statementCount += a.length; + + indent -= state.option.indent; + } else if (isfunc) { + // Ensure property is set for functions with empty bodies. + state.funct["(isStrict)"] = state.isStrict(); } - // It is valid to have a regular argument after a default argument - // since undefined can be used for missing parameters. Still warn as it is - // a possible code smell. - if (pastDefault) { - if (state.tokens.next.id !== "=") { - error("W138", state.tokens.current); + advance("}", t); + + if (isfunc) { + state.funct["(scope)"].validateParams(isfatarrow); + if (m) { + state.directive = m; } } - if (state.tokens.next.id === "=") { - if (!state.inES6()) { - warning("W119", state.tokens.next, "default parameters", "6"); + + state.funct["(scope)"].unstack(); + + indent = old_indent; + } else if (!ordinary) { + if (isfunc) { + state.funct["(scope)"].stack(); + + if (stmt && !isfatarrow && !state.inMoz()) { + error("W118", state.tokens.curr, "function closure expressions"); } - advance("="); - pastDefault = true; - expression(10); - } - // now we have evaluated the default expression, add the variable to the param scope - currentParams.forEach(addParam); + if (isfatarrow) { + state.funct["(scope)"].validateParams(true); + } - if (state.tokens.next.id === ",") { - if (pastRest) { - warning("W131", state.tokens.next); + var expr = expression(context, 10); + + if (state.option.noreturnawait && context & prodParams.async && + expr.identifier && expr.value === "await") { + warning("W146", expr); + } + + if (state.option.strict && state.funct["(context)"]["(global)"]) { + if (!state.isStrict()) { + warning("E007"); + } } - comma(); + + state.funct["(scope)"].unstack(); } else { - advance(")", next); - return { arity: arity, params: paramsIds }; + error("E021", state.tokens.next, "{", state.tokens.next.value); } - } - } + } else { - function functor(name, token, overwrites) { - var funct = { - "(name)" : name, - "(breakage)" : 0, - "(loopage)" : 0, - "(tokens)" : {}, - "(properties)": {}, + state.funct["(scope)"].stack(); - "(catch)" : false, - "(global)" : false, + if (!stmt || state.option.curly) { + warning("W116", state.tokens.next, "{", state.tokens.next.value); + } - "(line)" : null, - "(character)" : null, - "(metrics)" : null, - "(statement)" : null, - "(context)" : null, - "(scope)" : null, - "(comparray)" : null, - "(generator)" : null, - "(arrow)" : null, - "(params)" : null - }; + // JSHint observes Annex B of the ECMAScript specification by default, + // where function declarations are permitted in the statement positions + // of IfStatements. + var supportsFnDecl = state.funct["(verb)"] === "if" || + state.tokens.curr.id === "else"; - if (token) { - _.extend(funct, { - "(line)" : token.line, - "(character)": token.character, - "(metrics)" : createMetrics(token) - }); + state.tokens.next.inBracelessBlock = true; + indent += state.option.indent; + // test indentation only if statement is in new line + a = [statement(context)]; + indent -= state.option.indent; + + if (a[0] && a[0].declaration && + !(supportsFnDecl && a[0].id === "function")) { + error("E048", a[0], a[0].id[0].toUpperCase() + a[0].id.slice(1)); + } + + state.funct["(scope)"].unstack(); } - _.extend(funct, overwrites); + // Don't clear and let it propagate out if it is "break", "return" or + // similar in switch case + switch (state.funct["(verb)"]) { + case "break": + case "continue": + case "return": + case "throw": + if (iscase) { + break; + } - if (funct["(context)"]) { - funct["(scope)"] = funct["(context)"]["(scope)"]; - funct["(comparray)"] = funct["(context)"]["(comparray)"]; + /* falls through */ + default: + state.funct["(verb)"] = null; } - return funct; + inblock = b; + if (ordinary && state.option.noempty && (!a || a.length === 0)) { + warning("W035", state.tokens.prev); + } + metrics.nestedBlockDepth -= 1; + return a; } - function isFunctor(token) { - return "(scope)" in token; - } /** - * Determine if the parser has begun parsing executable code. + * Update the global state which tracks all statically-identifiable property + * names, and emit a warning if the `members` linting directive is in use and + * does not include the given name. * - * @param {Token} funct - The current "functor" token - * - * @returns {boolean} + * @param {string} m - the property name */ - function hasParsedCode(funct) { - return funct["(global)"] && !funct["(verb)"]; - } - - function doTemplateLiteral(left) { - // ASSERT: this.type === "(template)" - // jshint validthis: true - var ctx = this.context; - var noSubst = this.noSubst; - var depth = this.depth; - - if (!noSubst) { - while (!end()) { - if (!state.tokens.next.template || state.tokens.next.depth > depth) { - expression(0); // should probably have different rbp? - } else { - // skip template start / middle - advance(); - } - } + function countMember(m) { + if (membersOnly && typeof membersOnly[m] !== "boolean") { + warning("W036", state.tokens.curr, m); } - - return { - id: "(template)", - type: "(template)", - tag: left - }; - - function end() { - if (state.tokens.curr.template && state.tokens.curr.tail && - state.tokens.curr.context === ctx) return true; - var complete = (state.tokens.next.template && state.tokens.next.tail && - state.tokens.next.context === ctx); - if (complete) advance(); - return complete || state.tokens.next.isUnclosed; + if (typeof member[m] === "number") { + member[m] += 1; + } else { + member[m] = 1; } } - /** - * @param {Object} [options] - * @param {token} [options.name] The identifier belonging to the function (if - * any) - * @param {boolean} [options.statement] The statement that triggered creation - * of the current function. - * @param {string} [options.type] If specified, either "generator" or "arrow" - * @param {token} [options.loneArg] The argument to the function in cases - * where it was defined using the - * single-argument shorthand - * @param {bool} [options.parsedOpening] Whether the opening parenthesis has - * already been parsed - * @param {token} [options.classExprBinding] Define a function with this - * identifier in the new function's - * scope, mimicking the bahavior of - * class expression names within - * the body of member functions. - */ - function doFunction(options) { - var f, token, name, statement, classExprBinding, isGenerator, isArrow, ignoreLoopFunc; - var oldOption = state.option; - var oldIgnored = state.ignored; + // Build the syntax table by declaring the syntactic elements of the language. - if (options) { - name = options.name; - statement = options.statement; - classExprBinding = options.classExprBinding; - isGenerator = options.type === "generator"; - isArrow = options.type === "arrow"; - ignoreLoopFunc = options.ignoreLoopFunc; + type("(number)", function() { + if (state.tokens.next.id === ".") { + warning("W005", this); } - state.option = Object.create(state.option); - state.ignored = Object.create(state.ignored); - - state.funct = functor(name || state.nameStack.infer(), state.tokens.next, { - "(statement)": statement, - "(context)": state.funct, - "(arrow)": isArrow, - "(generator)": isGenerator - }); + return this; + }); - f = state.funct; - token = state.tokens.curr; - token.funct = state.funct; + type("(string)", function() { + return this; + }); - functions.push(state.funct); + state.syntax["(identifier)"] = { + type: "(identifier)", + lbp: 0, + identifier: true, - // So that the function is available to itself and referencing itself is not - // seen as a closure, add the function name to a new scope, but do not - // test for unused (unused: false) - // it is a new block scope so that params can override it, it can be block scoped - // but declarations inside the function don't cause already declared error - state.funct["(scope)"].stack("functionouter"); - var internallyAccessibleName = name || classExprBinding; - if (internallyAccessibleName) { - state.funct["(scope)"].block.add(internallyAccessibleName, - classExprBinding ? "class" : "function", state.tokens.curr, false); - } + nud: function(context) { + var v = this.value; + // If this identifier is the lone parameter to a shorthand "fat arrow" + // function definition, i.e. + // + // x => x; + // + // ...it should not be considered as a variable in the current scope. It + // will be added to the scope of the new function when the next token is + // parsed, so it can be safely ignored for now. + var isLoneArrowParam = state.tokens.next.id === "=>"; - // create the param scope (params added in functionparams) - state.funct["(scope)"].stack("functionparams"); + if (isReserved(context, this)) { + warning("W024", this, v); + } else if (!isLoneArrowParam && !state.funct["(comparray)"].check(v)) { + state.funct["(scope)"].block.use(v, state.tokens.curr); + } - var paramsInfo = functionparams(options); + return this; + }, - if (paramsInfo) { - state.funct["(params)"] = paramsInfo.params; - state.funct["(metrics)"].arity = paramsInfo.arity; - state.funct["(metrics)"].verifyMaxParametersPerFunction(); - } else { - state.funct["(metrics)"].arity = 0; + led: function() { + /* istanbul ignore next */ + error("E033", state.tokens.next, state.tokens.next.value); } + }; - if (isArrow) { - if (!state.inES6(true)) { - warning("W119", state.tokens.curr, "arrow function syntax (=>)", "6"); - } - - if (!options.loneArg) { - advance("=>"); - } - } + var baseTemplateSyntax = { + identifier: false, + template: true, + }; + state.syntax["(template)"] = _.extend({ + lbp: 155, + type: "(template)", + nud: doTemplateLiteral, + led: doTemplateLiteral, + noSubst: false + }, baseTemplateSyntax); - block(false, true, true, isArrow); + state.syntax["(template middle)"] = _.extend({ + lbp: 0, + type: "(template middle)", + noSubst: false + }, baseTemplateSyntax); - if (!state.option.noyield && isGenerator && - state.funct["(generator)"] !== "yielded") { - warning("W124", state.tokens.curr); - } + state.syntax["(template tail)"] = _.extend({ + lbp: 0, + type: "(template tail)", + tail: true, + noSubst: false + }, baseTemplateSyntax); - state.funct["(metrics)"].verifyMaxStatementsPerFunction(); - state.funct["(metrics)"].verifyMaxComplexityPerFunction(); - state.funct["(unusedOption)"] = state.option.unused; - state.option = oldOption; - state.ignored = oldIgnored; - state.funct["(last)"] = state.tokens.curr.line; - state.funct["(lastcharacter)"] = state.tokens.curr.character; + state.syntax["(no subst template)"] = _.extend({ + lbp: 155, + type: "(template)", + nud: doTemplateLiteral, + led: doTemplateLiteral, + noSubst: true, + tail: true // mark as tail, since it's always the last component + }, baseTemplateSyntax); - // unstack the params scope - state.funct["(scope)"].unstack(); // also does usage and label checks + type("(regexp)", function() { + return this; + }); - // unstack the function outer stack - state.funct["(scope)"].unstack(); + // ECMAScript parser - state.funct = state.funct["(context)"]; + delim("(endline)"); + (function(x) { + x.line = x.from = 0; + })(delim("(begin)")); + delim("(end)").reach = true; + delim("(error)").reach = true; + delim("}").reach = true; + delim(")"); + delim("]"); + delim("\"").reach = true; + delim("'").reach = true; + delim(";"); + delim(":").reach = true; + delim("#"); - if (!ignoreLoopFunc && !state.option.loopfunc && state.funct["(loopage)"]) { - // If the function we just parsed accesses any non-local variables - // trigger a warning. Otherwise, the function is safe even within - // a loop. - if (f["(isCapturing)"]) { - warning("W083", token); - } + reserve("else"); + reserve("case").reach = true; + reserve("catch"); + reserve("default").reach = true; + reserve("finally"); + reserve("true", function() { return this; }); + reserve("false", function() { return this; }); + reserve("null", function() { return this; }); + reserve("this", function() { + if (state.isStrict() && !isMethod() && + !state.option.validthis && ((state.funct["(statement)"] && + state.funct["(name)"].charAt(0) > "Z") || state.funct["(global)"])) { + warning("W040", this); } - return f; - } + return this; + }); - function createMetrics(functionStartToken) { - return { - statementCount: 0, - nestedBlockDepth: -1, - ComplexityCount: 1, - arity: 0, + (function(superSymbol) { + superSymbol.rbp = 161; + })(reserve("super", function() { + superNud.call(state.tokens.curr, this); - verifyMaxStatementsPerFunction: function() { - if (state.option.maxstatements && - this.statementCount > state.option.maxstatements) { - warning("W071", functionStartToken, this.statementCount); - } - }, + return this; + })); - verifyMaxParametersPerFunction: function() { - if (_.isNumber(state.option.maxparams) && - this.arity > state.option.maxparams) { - warning("W072", functionStartToken, this.arity); - } - }, + assignop("=", "assign"); + assignop("+=", "assignadd"); + assignop("-=", "assignsub"); + assignop("*=", "assignmult"); + assignop("/=", "assigndiv").nud = function() { + /* istanbul ignore next */ + error("E014"); + }; + assignop("%=", "assignmod"); + assignop("**=", function(context, left, that) { + if (!state.inES7()) { + warning("W119", that, "Exponentiation operator", "7"); + } - verifyMaxNestedBlockDepthPerFunction: function() { - if (state.option.maxdepth && - this.nestedBlockDepth > 0 && - this.nestedBlockDepth === state.option.maxdepth + 1) { - warning("W073", null, this.nestedBlockDepth); - } - }, + that.left = left; - verifyMaxComplexityPerFunction: function() { - var max = state.option.maxcomplexity; - var cc = this.ComplexityCount; - if (max && cc > max) { - warning("W074", functionStartToken, cc); - } - } - }; - } + checkLeftSideAssign(context, left, that); - function increaseComplexityCount() { - state.funct["(metrics)"].ComplexityCount += 1; - } + that.right = expression(context, 10); - // Parse assignments that were found instead of conditionals. - // For example: if (a = 1) { ... } + return that; + }); - function checkCondAssignment(expr) { - var id, paren; - if (expr) { - id = expr.id; - paren = expr.paren; - if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) { - id = expr.id; - paren = paren || expr.paren; - } - } - switch (id) { - case "=": - case "+=": - case "-=": - case "*=": - case "%=": - case "&=": - case "|=": - case "^=": - case "/=": - if (!paren && !state.option.boss) { - warning("W084"); - } + bitwiseassignop("&="); + bitwiseassignop("|="); + bitwiseassignop("^="); + bitwiseassignop("<<="); + bitwiseassignop(">>="); + bitwiseassignop(">>>="); + infix(",", function(context, left, that) { + if (state.option.nocomma) { + warning("W127", that); } - } - /** - * @param {object} props Collection of property descriptors for a given - * object. - */ - function checkProperties(props) { - // Check for lonely setters if in the ES5 mode. - if (state.inES5()) { - for (var name in props) { - if (props[name] && props[name].setterToken && !props[name].getterToken) { - warning("W078", props[name].setterToken); - } - } - } - } + that.left = left; - function metaProperty(name, c) { - if (checkPunctuator(state.tokens.next, ".")) { - var left = state.tokens.curr.id; - advance("."); - var id = identifier(); - state.tokens.curr.isMetaProperty = true; - if (name !== id) { - error("E057", state.tokens.prev, left, id); - } else { - c(); - } - return state.tokens.curr; + if (checkComma()) { + that.right = expression(context, 10); + } else { + that.right = null; } - } - (function(x) { - x.nud = function() { - var b, f, i, p, t, isGeneratorMethod = false, nextVal; - var props = Object.create(null); // All properties, including accessors + return that; + }, 10, true); - b = state.tokens.curr.line !== startLine(state.tokens.next); - if (b) { - indent += state.option.indent; - if (state.tokens.next.from === indent + state.option.indent) { - indent += state.option.indent; - } - } + infix("?", function(context, left, that) { + increaseComplexityCount(); + that.left = left; + that.right = expression(context & ~prodParams.noin, 10); + advance(":"); + expression(context, 10); + return that; + }, 30); - var blocktype = lookupBlockType(); - if (blocktype.isDestAssign) { - this.destructAssign = destructuringPattern({ openingParsed: true, assignment: true }); - return this; - } + infix("||", function(context, left, that) { + increaseComplexityCount(); + that.left = left; + that.right = expression(context, 40); + return that; + }, 40); - for (;;) { - if (state.tokens.next.id === "}") { - break; - } + var andPrecedence = 50; + infix("&&", function(context, left, that) { + increaseComplexityCount(); + that.left = left; + that.right = expression(context, andPrecedence); + return that; + }, andPrecedence); - nextVal = state.tokens.next.value; - if (state.tokens.next.identifier && - (peekIgnoreEOL().id === "," || peekIgnoreEOL().id === "}")) { - if (!state.inES6()) { - warning("W104", state.tokens.next, "object short notation", "6"); - } - i = propertyName(true); - saveProperty(props, i, state.tokens.next); + infix("??", function(context, left, that) { + if (!left.paren && (left.id === "||" || left.id === "&&")) { + error("E024", that, "??"); + } - expression(10); + if (!state.inES11()) { + warning("W119", that, "nullish coalescing", "11"); + } - } else if (peek().id !== ":" && (nextVal === "get" || nextVal === "set")) { - advance(nextVal); + increaseComplexityCount(); + that.left = left; + var right = that.right = expression(context, 39); - if (!state.inES5()) { - error("E034"); - } + if (!right) { + error("E024", state.tokens.next, state.tokens.next.id); + } else if (!right.paren && (right.id === "||" || right.id === "&&")) { + error("E024", that.right, that.right.id); + } - i = propertyName(); + return that; + }, 39); - // ES6 allows for get() {...} and set() {...} method - // definition shorthand syntax, so we don't produce an error - // if linting ECMAScript 6 code. - if (!i && !state.inES6()) { - error("E035"); - } + // The Exponentiation operator, introduced in ECMAScript 2016 + // + // ExponentiationExpression[Yield] : + // UnaryExpression[?Yield] + // UpdateExpression[?Yield] ** ExponentiationExpression[?Yield] + infix("**", function(context, left, that) { + if (!state.inES7()) { + warning("W119", that, "Exponentiation operator", "7"); + } - // We don't want to save this getter unless it's an actual getter - // and not an ES6 concise method - if (i) { - saveAccessor(nextVal, props, i, state.tokens.curr); - } + // Disallow UnaryExpressions which are not wrapped in parenthesis + if (!left.paren && beginsUnaryExpression(left)) { + error("E024", that, "**"); + } - t = state.tokens.next; - f = doFunction(); - p = f["(params)"]; + that.left = left; + that.right = expression(context, that.rbp); + return that; + }, 150); + state.syntax["**"].rbp = 140; + bitwise("|", "bitor", 70); + bitwise("^", "bitxor", 80); + bitwise("&", "bitand", 90); + relation("==", function(context, left, right) { + var eqnull = state.option.eqnull && + ((left && left.value) === "null" || (right && right.value) === "null"); - // Don't warn about getter/setter pairs if this is an ES6 concise method - if (nextVal === "get" && i && p) { - warning("W076", t, p[0], i); - } else if (nextVal === "set" && i && (!p || p.length !== 1)) { - warning("W077", t, i); - } - } else { - if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") { - if (!state.inES6()) { - warning("W104", state.tokens.next, "generator functions", "6"); - } - advance("*"); - isGeneratorMethod = true; - } else { - isGeneratorMethod = false; - } + switch (true) { + case !eqnull && state.option.eqeqeq: + this.from = this.character; + warning("W116", this, "===", "=="); + break; + /* istanbul ignore next */ + case isTypoTypeof(right, left, state): + warning("W122", this, right.value); + break; + case isTypoTypeof(left, right, state): + warning("W122", this, left.value); + break; + } - if (state.tokens.next.id === "[") { - i = computedPropertyName(); - state.nameStack.set(i); - } else { - state.nameStack.set(state.tokens.next); - i = propertyName(); - saveProperty(props, i, state.tokens.next); + return this; + }); + relation("===", function(context, left, right) { + if (isTypoTypeof(right, left, state)) { + warning("W122", this, right.value); + } else if (isTypoTypeof(left, right, state)) { + /* istanbul ignore next */ + warning("W122", this, left.value); + } + return this; + }); + relation("!=", function(context, left, right) { + var eqnull = state.option.eqnull && + ((left && left.value) === "null" || (right && right.value) === "null"); - if (typeof i !== "string") { - break; - } - } + if (!eqnull && state.option.eqeqeq) { + this.from = this.character; + warning("W116", this, "!==", "!="); + } else if (isTypoTypeof(right, left, state)) { + /* istanbul ignore next */ + warning("W122", this, right.value); + } else if (isTypoTypeof(left, right, state)) { + warning("W122", this, left.value); + } + return this; + }); + relation("!==", function(context, left, right) { + if (isTypoTypeof(right, left, state)) { + warning("W122", this, right.value); + } else if (isTypoTypeof(left, right, state)) { + /* istanbul ignore next */ + warning("W122", this, left.value); + } + return this; + }); + relation("<"); + relation(">"); + relation("<="); + relation(">="); + bitwise("<<", "shiftleft", 120); + bitwise(">>", "shiftright", 120); + bitwise(">>>", "shiftrightunsigned", 120); + infix("in", "in", 120); + infix("instanceof", function(context, left, token) { + var right; + var scope = state.funct["(scope)"]; + token.left = left; + token.right = right = expression(context, 120); - if (state.tokens.next.value === "(") { - if (!state.inES6()) { - warning("W104", state.tokens.curr, "concise methods", "6"); - } - doFunction({ type: isGeneratorMethod ? "generator" : null }); - } else { - advance(":"); - expression(10); - } - } + // This condition reflects a syntax error which will be reported by the + // `expression` function. + if (!right) { + return token; + } - countMember(i); + if (right.id === "(number)" || + right.id === "(string)" || + right.value === "null" || + (right.value === "undefined" && !scope.has("undefined")) || + right.arity === "unary" || + right.id === "{" || + (right.id === "[" && !right.right) || + right.id === "(regexp)" || + (right.id === "(template)" && !right.tag)) { + error("E060"); + } - if (state.tokens.next.id === ",") { - comma({ allowTrailing: true, property: true }); - if (state.tokens.next.id === ",") { - warning("W070", state.tokens.curr); - } else if (state.tokens.next.id === "}" && !state.inES5()) { - warning("W070", state.tokens.curr); - } - } else { - break; - } - } - if (b) { - indent -= state.option.indent; + if (right.id === "function") { + warning("W139"); + } + + return token; + }, 120); + infix("+", function(context, left, that) { + var next = state.tokens.next; + var right; + that.left = left; + that.right = right = expression(context, 130); + + if (left && right && left.id === "(string)" && right.id === "(string)") { + left.value += right.value; + left.character = right.character; + if (!state.option.scripturl && reg.javascriptURL.test(left.value)) { + warning("W050", left); } - advance("}", this); + return left; + } - checkProperties(props); + if (next.id === "+" || next.id === "++") { + warning("W007", that.right); + } + + return that; + }, 130); + prefix("+", function(context) { + var next = state.tokens.next; + this.arity = "unary"; + this.right = expression(context, 150); + + if (next.id === "+" || next.id === "++") { + warning("W007", this.right); + } + + return this; + }); + infix("-", function(context, left, that) { + var next = state.tokens.next; + that.left = left; + that.right = expression(context, 130); + + if (next.id === "-" || next.id === "--") { + warning("W006", that.right); + } + + return that; + }, 130); + prefix("-", function(context) { + var next = state.tokens.next; + this.arity = "unary"; + this.right = expression(context, 150); + + if (next.id === "-" || next.id === "--") { + warning("W006", this.right); + } + + return this; + }); + infix("*", "mult", 140); + infix("/", "div", 140); + infix("%", "mod", 140); + + suffix("++"); + prefix("++", "preinc"); + state.syntax["++"].exps = true; + + suffix("--"); + prefix("--", "predec"); + state.syntax["--"].exps = true; + prefix("delete", function(context) { + this.arity = "unary"; + var p = expression(context, 150); + if (!p) { return this; - }; - x.fud = function() { - error("E036", state.tokens.curr); - }; - }(delim("{"))); + } - function destructuringPattern(options) { - var isAssignment = options && options.assignment; + if (p.id !== "." && p.id !== "[") { + warning("W051"); + } + this.first = p; - if (!state.inES6()) { - warning("W104", state.tokens.curr, - isAssignment ? "destructuring assignment" : "destructuring binding", "6"); + // The `delete` operator accepts unresolvable references when not in strict + // mode, so the operand may be undefined. + if (p.identifier && !state.isStrict()) { + p.forgiveUndef = true; } + return this; + }).exps = true; - return destructuringPatternRecursive(options); - } + prefix("~", function(context) { + if (state.option.bitwise) { + warning("W016", this, "~"); + } + this.arity = "unary"; + this.right = expression(context, 150); + return this; + }); - function destructuringPatternRecursive(options) { - var ids; - var identifiers = []; - var openingParsed = options && options.openingParsed; - var isAssignment = options && options.assignment; - var recursiveOptions = isAssignment ? { assignment: isAssignment } : null; - var firstToken = openingParsed ? state.tokens.curr : state.tokens.next; + infix("..."); - var nextInnerDE = function() { - var ident; - if (checkPunctuators(state.tokens.next, ["[", "{"])) { - ids = destructuringPatternRecursive(recursiveOptions); - for (var id in ids) { - id = ids[id]; - identifiers.push({ id: id.id, token: id.token }); - } - } else if (checkPunctuator(state.tokens.next, ",")) { - identifiers.push({ id: null, token: state.tokens.curr }); - } else if (checkPunctuator(state.tokens.next, "(")) { - advance("("); - nextInnerDE(); - advance(")"); - } else { - var is_rest = checkPunctuator(state.tokens.next, "..."); + prefix("!", function(context) { + this.arity = "unary"; + this.right = expression(context, 150); - if (isAssignment) { - var identifierToken = is_rest ? peek(0) : state.tokens.next; - if (!identifierToken.identifier) { - warning("E030", identifierToken, identifierToken.value); - } - var assignTarget = expression(155); - if (assignTarget) { - checkLeftSideAssign(assignTarget); + if (!this.right) { // '!' followed by nothing? Give up. + quit("E041", this); + } - // if the target was a simple identifier, add it to the list to return - if (assignTarget.identifier) { - ident = assignTarget.value; - } - } - } else { - ident = identifier(); - } - if (ident) { - identifiers.push({ id: ident, token: state.tokens.curr }); - } - return is_rest; + if (bang[this.right.id] === true) { + warning("W018", this, "!"); + } + return this; + }); + + prefix("typeof", function(context) { + this.arity = "unary"; + var p = expression(context, 150); + this.first = this.right = p; + + if (!p) { // 'typeof' followed by nothing? Give up. + quit("E041", this); + } + + // The `typeof` operator accepts unresolvable references, so the operand + // may be undefined. + if (p.identifier) { + p.forgiveUndef = true; + } + return this; + }); + prefix("new", function(context) { + var mp = metaProperty(context, "target", function() { + if (!state.inES6(true)) { + warning("W119", state.tokens.prev, "new.target", "6"); } - return false; - }; - var assignmentProperty = function() { - var id; - if (checkPunctuator(state.tokens.next, "[")) { - advance("["); - expression(10); - advance("]"); - advance(":"); - nextInnerDE(); - } else if (state.tokens.next.id === "(string)" || - state.tokens.next.id === "(number)") { - advance(); - advance(":"); - nextInnerDE(); - } else { - // this id will either be the property name or the property name and the assigning identifier - id = identifier(); - if (checkPunctuator(state.tokens.next, ":")) { - advance(":"); - nextInnerDE(); - } else if (id) { - // in this case we are assigning (not declaring), so check assignment - if (isAssignment) { - checkLeftSideAssign(state.tokens.curr); - } - identifiers.push({ id: id, token: state.tokens.curr }); - } - } - }; - if (checkPunctuator(firstToken, "[")) { - if (!openingParsed) { - advance("["); + var inFunction, c = state.funct; + while (c) { + inFunction = !c["(global)"]; + if (!c["(arrow)"]) { break; } + c = c["(context)"]; } - if (checkPunctuator(state.tokens.next, "]")) { - warning("W137", state.tokens.curr); + if (!inFunction) { + warning("W136", state.tokens.prev, "new.target"); } - var element_after_rest = false; - while (!checkPunctuator(state.tokens.next, "]")) { - if (nextInnerDE() && !element_after_rest && - checkPunctuator(state.tokens.next, ",")) { - warning("W130", state.tokens.next); - element_after_rest = true; - } - if (checkPunctuator(state.tokens.next, "=")) { - if (checkPunctuator(state.tokens.prev, "...")) { - advance("]"); - } else { - advance("="); + }); + if (mp) { return mp; } + + var opening = state.tokens.next; + var c = expression(context, 155), i; + + if (!c) { + return this; + } + + if (!c.paren && c.rbp > 160) { + error("E024", opening, opening.value); + } + + if (c.id !== "function") { + if (c.identifier) { + switch (c.value) { + case "Number": + case "String": + case "Boolean": + case "Math": + case "JSON": + warning("W053", state.tokens.prev, c.value); + break; + case "Symbol": + if (state.inES6()) { + warning("W053", state.tokens.prev, c.value); } - if (state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); + break; + case "Function": + if (!state.option.evil) { + warning("W054"); } - expression(10); - } - if (!checkPunctuator(state.tokens.next, "]")) { - advance(","); - } - } - advance("]"); - } else if (checkPunctuator(firstToken, "{")) { - - if (!openingParsed) { - advance("{"); - } - if (checkPunctuator(state.tokens.next, "}")) { - warning("W137", state.tokens.curr); - } - while (!checkPunctuator(state.tokens.next, "}")) { - assignmentProperty(); - if (checkPunctuator(state.tokens.next, "=")) { - advance("="); - if (state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); + break; + case "Date": + case "RegExp": + case "this": + break; + default: + i = c.value.substr(0, 1); + if (state.option.newcap && (i < "A" || i > "Z") && + !state.funct["(scope)"].isPredefined(c.value)) { + warning("W055", state.tokens.curr); } - expression(10); } - if (!checkPunctuator(state.tokens.next, "}")) { - advance(","); - if (checkPunctuator(state.tokens.next, "}")) { - // Trailing comma - // ObjectBindingPattern: { BindingPropertyList , } - break; - } + } else { + if (c.id === "?." && !c.paren) { + error("E024", c, "?."); + } else if (c.id !== "." && c.id !== "[" && c.id !== "(") { + /* istanbul ignore next */ + warning("W056", state.tokens.curr); } } - advance("}"); + } else { + if (!state.option.supernew) + warning("W057", this); } - return identifiers; - } - - function destructuringPatternMatch(tokens, value) { - var first = value.first; - - if (!first) - return; - - _.zip(tokens, Array.isArray(first) ? first : [ first ]).forEach(function(val) { - var token = val[0]; - var value = val[1]; - - if (token && value) - token.first = value; - else if (token && token.first && !value) - warning("W080", token.first, token.first.value); - }); - } + if (state.tokens.next.id !== "(" && !state.option.supernew) { + warning("W058", state.tokens.curr, state.tokens.curr.value); + } + this.first = this.right = c; + return this; + }); + state.syntax["new"].exps = true; - function blockVariableStatement(type, statement, context) { - // used for both let and const statements - var prefix = context && context.prefix; - var inexport = context && context.inexport; - var isLet = type === "let"; - var isConst = type === "const"; - var tokens, lone, value, letblock; + var classDeclaration = blockstmt("class", function(context) { + var className, classNameToken; if (!state.inES6()) { - warning("W104", state.tokens.curr, type, "6"); + warning("W104", state.tokens.curr, "class", "6"); } + state.inClassBody = true; - if (isLet && state.tokens.next.value === "(") { - if (!state.inMoz()) { - warning("W118", state.tokens.next, "let block"); - } - advance("("); - state.funct["(scope)"].stack(); - letblock = true; - } else if (state.funct["(noblockscopedvar)"]) { - error("E048", state.tokens.curr, isConst ? "Const" : "Let"); + // Class Declaration: 'class ' + if (state.tokens.next.identifier && state.tokens.next.value !== "extends") { + classNameToken = state.tokens.next; + className = classNameToken.value; + identifier(context); + // unintialized, so that the 'extends' clause is parsed while the class is in TDZ + state.funct["(scope)"].addbinding(className, { + type: "class", + initialized: false, + token: classNameToken + }); } - statement.first = []; - for (;;) { - var names = []; - if (_.contains(["{", "["], state.tokens.next.value)) { - tokens = destructuringPattern(); - lone = false; - } else { - tokens = [ { id: identifier(), token: state.tokens.curr } ]; - lone = true; - } + // Class Declaration: 'class extends ' + if (state.tokens.next.value === "extends") { + advance("extends"); + expression(context, 0); + } - if (!prefix && isConst && state.tokens.next.id !== "=") { - warning("E012", state.tokens.curr, state.tokens.curr.value); - } + if (classNameToken) { + this.name = classNameToken; + state.funct["(scope)"].initialize(className); + } else { + this.name = null; + } - for (var t in tokens) { - if (tokens.hasOwnProperty(t)) { - t = tokens[t]; - if (state.funct["(scope)"].block.isGlobal()) { - if (predefined[t.id] === false) { - warning("W079", t.token, t.id); - } - } - if (t.id && !state.funct["(noblockscopedvar)"]) { - state.funct["(scope)"].addlabel(t.id, { - type: type, - token: t.token }); - names.push(t.token); + state.funct["(scope)"].stack(); + classBody(this, context); + return this; + }); + classDeclaration.exps = true; + classDeclaration.declaration = true; - if (lone && inexport) { - state.funct["(scope)"].setExported(t.token.value, t.token); - } - } - } - } + /* + Class expression - if (state.tokens.next.id === "=") { - advance("="); - if (!prefix && state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); - } - if (!prefix && peek(0).id === "=" && state.tokens.next.identifier) { - warning("W120", state.tokens.next, state.tokens.next.value); - } - // don't accept `in` in expression if prefix is used for ForIn/Of loop. - value = expression(prefix ? 120 : 10); - if (lone) { - tokens[0].first = value; - } else { - destructuringPatternMatch(names, value); - } - } + The Block- and Expression- handling for "class" are almost identical, except for the ordering of steps. + In an expression:, the name should not be saved into the calling scope, but is still accessible inside the definition, so we open a new scope first, then save the name. We also mark it as used. + */ + prefix("class", function(context) { + var className, classNameToken; - statement.first = statement.first.concat(names); + if (!state.inES6()) { + warning("W104", state.tokens.curr, "class", "6"); + } + state.inClassBody = true; - if (state.tokens.next.id !== ",") { - break; - } - comma(); + // Class Declaration: 'class ' + if (state.tokens.next.identifier && state.tokens.next.value !== "extends") { + classNameToken = state.tokens.next; + className = classNameToken.value; + identifier(context); } - if (letblock) { - advance(")"); - block(true, true); - statement.block = true; - state.funct["(scope)"].unstack(); + + // Class Declaration: 'class extends ' + if (state.tokens.next.value === "extends") { + advance("extends"); + expression(context, 0); } - return statement; - } + state.funct["(scope)"].stack(); + if (classNameToken) { + this.name = classNameToken; + state.funct["(scope)"].addbinding(className, { + type: "class", + initialized: true, + token: classNameToken + }); + state.funct["(scope)"].block.use(className, classNameToken); + } else { + this.name = null; + } - var conststatement = stmt("const", function(context) { - return blockVariableStatement("const", this, context); + classBody(this, context); + return this; }); - conststatement.exps = true; - var letstatement = stmt("let", function(context) { - return blockVariableStatement("let", this, context); - }); - letstatement.exps = true; + function classBody(classToken, context) { + var props = Object.create(null); + var name, accessorType, token, isStatic, inGenerator, hasConstructor; - var varstatement = stmt("var", function(context) { - var prefix = context && context.prefix; - var inexport = context && context.inexport; - var tokens, lone, value; + /* istanbul ignore else */ + if (state.tokens.next.value === "{") { + advance("{"); + } else { + warning("W116", state.tokens.curr, "identifier", state.tokens.next.type); //? + advance(); + } - // If the `implied` option is set, bindings are set differently. - var implied = context && context.implied; - var report = !(context && context.ignore); + while (state.tokens.next.value !== "}") { + isStatic = false; + inGenerator = false; + context &= ~prodParams.preAsync; - this.first = []; - for (;;) { - var names = []; - if (_.contains(["{", "["], state.tokens.next.value)) { - tokens = destructuringPattern(); - lone = false; - } else { - tokens = [ { id: identifier(), token: state.tokens.curr } ]; - lone = true; + if (state.tokens.next.value === "static" && + !checkPunctuator(peek(), "(")) { + isStatic = true; + advance(); } - if (!(prefix && implied) && report && state.option.varstmt) { - warning("W132", this); - } + if (state.tokens.next.value === "async") { + if (!checkPunctuator(peek(), "(")) { + context |= prodParams.preAsync; + advance(); - this.first = this.first.concat(names); + nolinebreak(state.tokens.curr); - for (var t in tokens) { - if (tokens.hasOwnProperty(t)) { - t = tokens[t]; - if (!implied && state.funct["(global)"]) { - if (predefined[t.id] === false) { - warning("W079", t.token, t.id); - } else if (state.option.futurehostile === false) { - if ((!state.inES5() && vars.ecmaIdentifiers[5][t.id] === false) || - (!state.inES6() && vars.ecmaIdentifiers[6][t.id] === false)) { - warning("W129", t.token, t.id); - } + if (checkPunctuator(state.tokens.next, "*")) { + inGenerator = true; + advance("*"); + + if (!state.inES9()) { + warning("W119", state.tokens.next, "async generators", "9"); } } - if (t.id) { - if (implied === "for") { - - if (!state.funct["(scope)"].has(t.id)) { - if (report) warning("W088", t.token, t.id); - } - state.funct["(scope)"].block.use(t.id, t.token); - } else { - state.funct["(scope)"].addlabel(t.id, { - type: "var", - token: t.token }); - if (lone && inexport) { - state.funct["(scope)"].setExported(t.id, t.token); - } - } - names.push(t.token); + if (!state.inES8()) { + warning("W119", state.tokens.curr, "async functions", "8"); } } } - if (state.tokens.next.id === "=") { - state.nameStack.set(state.tokens.curr); + if (state.tokens.next.value === "*") { + inGenerator = true; + advance(); + } - advance("="); - if (!prefix && report && !state.funct["(loopage)"] && - state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); - } - if (peek(0).id === "=" && state.tokens.next.identifier) { - if (!prefix && report && - !state.funct["(params)"] || - state.funct["(params)"].indexOf(state.tokens.next.value) === -1) { - warning("W120", state.tokens.next, state.tokens.next.value); - } - } - // don't accept `in` in expression if prefix is used for ForIn/Of loop. - value = expression(prefix ? 120 : 10); - if (lone) { - tokens[0].first = value; - } else { - destructuringPatternMatch(names, value); + token = state.tokens.next; + + if ((token.value === "set" || token.value === "get") && !checkPunctuator(peek(), "(")) { + if (inGenerator) { + /* istanbul ignore next */ + error("E024", token, token.value); } - } + accessorType = token.value; + advance(); + token = state.tokens.next; - if (state.tokens.next.id !== ",") { - break; + if (!isStatic && token.value === "constructor") { + error("E049", token, "class " + accessorType + "ter method", token.value); + } else if (isStatic && token.value === "prototype") { + error("E049", token, "static class " + accessorType + "ter method", token.value); + } + } else { + accessorType = null; } - comma(); - } - - return this; - }); - varstatement.exps = true; - - blockstmt("class", function() { - return classdef.call(this, true); - }); - function classdef(isStatement) { + switch (token.value) { + case ";": + warning("W032", token); + advance(); + break; + case "constructor": + if (isStatic) { + // treat like a regular method -- static methods can be called 'constructor' + name = propertyName(context); + saveProperty(props, name, token, true, isStatic); + doMethod(classToken, context, name, inGenerator); + } else { + if (inGenerator || context & prodParams.preAsync) { + error("E024", token, token.value); + } else if (hasConstructor) { + /* istanbul ignore next */ + error("E024", token, token.value); + } else { + hasConstructor = !accessorType && !isStatic; + } + advance(); + doMethod(classToken, context, state.nameStack.infer()); + } + break; + case "[": + name = computedPropertyName(context); + doMethod(classToken, context, name, inGenerator); + // We don't check names (via calling saveProperty()) of computed expressions like ["Symbol.iterator"]() + break; + default: + name = propertyName(context); + if (name === undefined) { + error("E024", token, token.value); + advance(); + break; + } - /*jshint validthis:true */ - if (!state.inES6()) { - warning("W104", state.tokens.curr, "class", "6"); - } - if (isStatement) { - // BindingIdentifier - this.name = identifier(); + if (accessorType) { + saveAccessor(accessorType, props, name, token, true, isStatic); + name = state.nameStack.infer(); + } else { + if (isStatic && name === "prototype") { + error("E049", token, "static class method", name); + } - state.funct["(scope)"].addlabel(this.name, { - type: "class", - token: state.tokens.curr }); - } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") { - // BindingIdentifier(opt) - this.name = identifier(); - this.namedExpr = true; - } else { - this.name = state.nameStack.infer(); - } - classtail(this); - return this; - } + saveProperty(props, name, token, true, isStatic); + } - function classtail(c) { - var wasInClassBody = state.inClassBody; - // ClassHeritage(opt) - if (state.tokens.next.value === "extends") { - advance("extends"); - c.heritage = expression(10); + doMethod(classToken, context, name, inGenerator); + break; + } } - - state.inClassBody = true; - advance("{"); - // ClassBody(opt) - c.body = classbody(c); advance("}"); - state.inClassBody = wasInClassBody; + checkProperties(props); + + state.inClassBody = false; + state.funct["(scope)"].unstack(); } - function classbody(c) { - var name; - var isStatic; - var isGenerator; - var getset; - var props = Object.create(null); - var staticProps = Object.create(null); - var computed; - for (var i = 0; state.tokens.next.id !== "}"; ++i) { - name = state.tokens.next; - isStatic = false; - isGenerator = false; - getset = null; - - // The ES6 grammar for ClassElement includes the `;` token, but it is - // defined only as a placeholder to facilitate future language - // extensions. In ES6 code, it serves no purpose. - if (name.id === ";") { - warning("W032"); - advance(";"); - continue; + function doMethod(classToken, context, name, generator) { + if (generator) { + if (!state.inES6()) { + warning("W119", state.tokens.curr, "function*", "6"); } + } - if (name.id === "*") { - isGenerator = true; - advance("*"); - name = state.tokens.next; - } - if (name.id === "[") { - name = computedPropertyName(); - computed = true; - } else if (isPropertyName(name)) { - // Non-Computed PropertyName + if (state.tokens.next.value !== "(") { + error("E054", state.tokens.next, state.tokens.next.value); + advance(); + if (state.tokens.next.value === "{") { + // manually cheating the test "invalidClasses", which asserts this particular behavior when a class is misdefined. advance(); - computed = false; - if (name.identifier && name.value === "static") { - if (checkPunctuator(state.tokens.next, "*")) { - isGenerator = true; - advance("*"); - } - if (isPropertyName(state.tokens.next) || state.tokens.next.id === "[") { - computed = state.tokens.next.id === "["; - isStatic = true; - name = state.tokens.next; - if (state.tokens.next.id === "[") { - name = computedPropertyName(); - } else advance(); - } - } - - if (name.identifier && (name.value === "get" || name.value === "set")) { - if (isPropertyName(state.tokens.next) || state.tokens.next.id === "[") { - computed = state.tokens.next.id === "["; - getset = name; - name = state.tokens.next; - if (state.tokens.next.id === "[") { - name = computedPropertyName(); - } else advance(); - } + if (state.tokens.next.value === "}") { + warning("W116", state.tokens.next, "(", state.tokens.next.value); + advance(); + identifier(context); + advance(); } + /* istanbul ignore next */ + return; } else { - warning("W052", state.tokens.next, state.tokens.next.value || state.tokens.next.type); - advance(); - continue; - } - - if (!checkPunctuator(state.tokens.next, "(")) { - // error --- class properties must be methods - error("E054", state.tokens.next, state.tokens.next.value); - while (state.tokens.next.id !== "}" && - !checkPunctuator(state.tokens.next, "(")) { + while (state.tokens.next.value !== "(") { advance(); } - if (state.tokens.next.value !== "(") { - doFunction({ statement: c }); - } } + } - if (!computed) { - // We don't know how to determine if we have duplicate computed property names :( - if (getset) { - saveAccessor( - getset.value, isStatic ? staticProps : props, name.value, name, true, isStatic); - } else { - if (name.value === "constructor") { - state.nameStack.set(c); - } else { - state.nameStack.set(name); - } - saveProperty(isStatic ? staticProps : props, name.value, name, true, isStatic); - } - } + doFunction(context, { name: name, + type: generator ? "generator" : null, + isMethod: true, + statement: classToken }); + } - if (getset && name.value === "constructor") { - var propDesc = getset.value === "get" ? "class getter method" : "class setter method"; - error("E049", name, propDesc, "constructor"); - } else if (name.value === "prototype") { - error("E049", name, "class method", "prototype"); - } + prefix("void").exps = true; - propertyName(name); + infix(".", function(context, left, that) { + var m = identifier(context, true); - doFunction({ - statement: c, - type: isGenerator ? "generator" : null, - classExprBinding: c.namedExpr ? c.name : null - }); + if (typeof m === "string") { + countMember(m); } - checkProperties(props); - } + that.left = left; + that.right = m; - blockstmt("function", function(context) { - var inexport = context && context.inexport; - var generator = false; - if (state.tokens.next.value === "*") { - advance("*"); - if (state.inES6({ strict: true })) { - generator = true; - } else { - warning("W119", state.tokens.curr, "function*", "6"); - } - } - if (inblock) { - warning("W082", state.tokens.curr); + if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") { + warning("W001"); } - var i = optionalidentifier(); - state.funct["(scope)"].addlabel(i, { - type: "function", - token: state.tokens.curr }); - - if (i === undefined) { - warning("W025"); - } else if (inexport) { - state.funct["(scope)"].setExported(i, state.tokens.prev); + if (left && left.value === "arguments" && (m === "callee" || m === "caller")) { + if (state.option.noarg) + warning("W059", left, m); + else if (state.isStrict()) + error("E008"); + } else if (!state.option.evil && left && left.value === "document" && + (m === "write" || m === "writeln")) { + warning("W060", left); } - doFunction({ - name: i, - statement: this, - type: generator ? "generator" : null, - ignoreLoopFunc: inblock // a declaration may already have warned - }); - if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) { - error("E039"); + if (!state.option.evil && (m === "eval" || m === "execScript")) { + if (isGlobalEval(left, state)) { + warning("W061"); + } } - return this; - }); - prefix("function", function() { - var generator = false; + return that; + }, 160, true); - if (state.tokens.next.value === "*") { - if (!state.inES6()) { - warning("W119", state.tokens.curr, "function*", "6"); - } - advance("*"); - generator = true; + infix("?.", function(context, left, that) { + if (!state.inES11()) { + warning("W119", state.tokens.curr, "Optional chaining", "11"); } - var i = optionalidentifier(); - doFunction({ name: i, type: generator ? "generator" : null }); - return this; - }); - blockstmt("if", function() { - var t = state.tokens.next; - increaseComplexityCount(); - state.condition = true; - advance("("); - var expr = expression(0); - checkCondAssignment(expr); + if (checkPunctuator(state.tokens.next, "[")) { + that.left = left; + advance(); + that.right = state.tokens.curr.led(context, left); + } else if (checkPunctuator(state.tokens.next, "(")) { + that.left = left; + advance(); + that.right = state.tokens.curr.led(context, left); + that.exps = true; + } else { + state.syntax["."].led.call(that, context, left); + } - // When the if is within a for-in loop, check if the condition - // starts with a negation operator - var forinifcheck = null; - if (state.option.forin && state.forinifcheckneeded) { - state.forinifcheckneeded = false; // We only need to analyze the first if inside the loop - forinifcheck = state.forinifchecks[state.forinifchecks.length - 1]; - if (expr.type === "(punctuator)" && expr.value === "!") { - forinifcheck.type = "(negative)"; - } else { - forinifcheck.type = "(positive)"; - } + if (state.tokens.next.type === "(template)") { + error("E024", state.tokens.next, "`"); } - advance(")", t); - state.condition = false; - var s = block(true, true); + return that; + }, 160, true); - // When the if is within a for-in loop and the condition has a negative form, - // check if the body contains nothing but a continue statement - if (forinifcheck && forinifcheck.type === "(negative)") { - if (s && s[0] && s[0].type === "(identifier)" && s[0].value === "continue") { - forinifcheck.type = "(negative-with-continue)"; - } - } - if (state.tokens.next.id === "else") { - advance("else"); - if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") { - statement(); - } else { - block(true, true); - } - } - return this; - }); + /** + * Determine if a CallExpression's "base" is a type of expression commonly + * used in this position. + * + * @param {token} token - token describing the "base" of the CallExpression + * @returns {boolean} + */ + function isTypicalCallExpression(token) { + return token.identifier || token.id === "." || token.id === "[" || + token.id === "=>" || token.id === "(" || token.id === "&&" || + token.id === "||" || token.id === "?" || token.id === "async" || + token.id === "?." || (state.inES6() && token["(name)"]); + } - blockstmt("try", function() { - var b; + infix("(", function(context, left, that) { + if (state.option.immed && left && !left.immed && left.id === "function") { + warning("W062"); + } - function doCatch() { - advance("catch"); - advance("("); + if (state.option.asi && checkPunctuators(state.tokens.prev, [")", "]"]) && + !sameLine(state.tokens.prev, state.tokens.curr)) { + warning("W014", state.tokens.curr, state.tokens.curr.id); + } - state.funct["(scope)"].stack("catchparams"); + var n = 0; + var p = []; - if (checkPunctuators(state.tokens.next, ["[", "{"])) { - var tokens = destructuringPattern(); - _.each(tokens, function(token) { - if (token.id) { - state.funct["(scope)"].addParam(token.id, token, "exception"); + if (left) { + if (left.type === "(identifier)") { + var newcapRe = /^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/; + var newcapIgnore = [ + "Array", "Boolean", "Date", "Error", "Function", "Number", + "Object", "RegExp", "String", "Symbol" + ]; + if (newcapRe.test(left.value) && newcapIgnore.indexOf(left.value) === -1) { + if (left.value === "Math") { + /* istanbul ignore next */ + warning("W063", left); + } else if (state.option.newcap) { + warning("W064", left); } - }); - } else if (state.tokens.next.type !== "(identifier)") { - warning("E030", state.tokens.next, state.tokens.next.value); - } else { - // only advance if we have an identifier so we can continue parsing in the most common error - that no param is given. - state.funct["(scope)"].addParam(identifier(), state.tokens.curr, "exception"); - } - - if (state.tokens.next.value === "if") { - if (!state.inMoz()) { - warning("W118", state.tokens.curr, "catch filter"); } - advance("if"); - expression(0); } + } - advance(")"); - - block(false); + if (state.tokens.next.id !== ")") { + for (;;) { + spreadrest("spread"); - state.funct["(scope)"].unstack(); - } + p[p.length] = expression(context, 10); + n += 1; + if (state.tokens.next.id !== ",") { + break; + } + advance(","); + checkComma({ allowTrailing: true }); - block(true); + if (state.tokens.next.id === ")") { + if (!state.inES8()) { + warning("W119", state.tokens.curr, "Trailing comma in arguments lists", "8"); + } - while (state.tokens.next.id === "catch") { - increaseComplexityCount(); - if (b && (!state.inMoz())) { - warning("W118", state.tokens.next, "multiple catch blocks"); + break; + } } - doCatch(); - b = true; } - if (state.tokens.next.id === "finally") { - advance("finally"); - block(true); - return; - } + advance(")"); - if (!b) { - error("E021", state.tokens.next, "catch", state.tokens.next.value); - } + if (typeof left === "object") { + if (!state.inES5() && left.value === "parseInt" && n === 1) { + warning("W065", state.tokens.curr); + } + if (!state.option.evil) { + if (left.value === "eval" || left.value === "Function" || + left.value === "execScript") { + warning("W061", left); - return this; - }); + // This conditional expression was initially implemented with a typo + // which prevented the branch's execution in all cases. While + // enabling the code will produce behavior that is consistent with + // the other forms of code evaluation that follow, such a change is + // also technically incompatable with prior versions of JSHint (due + // to the fact that the behavior was never formally documented). This + // branch should be enabled as part of a major release. + //if (p[0] && p[0].id === "(string)") { + // addEvalCode(left, p[0]); + //} + } else if (p[0] && p[0].id === "(string)" && + (left.value === "setTimeout" || + left.value === "setInterval")) { + warning("W066", left); + addEvalCode(left, p[0]); - blockstmt("while", function() { - var t = state.tokens.next; - state.funct["(breakage)"] += 1; - state.funct["(loopage)"] += 1; - increaseComplexityCount(); - advance("("); - checkCondAssignment(expression(0)); - advance(")", t); - block(true, true); - state.funct["(breakage)"] -= 1; - state.funct["(loopage)"] -= 1; - return this; - }).labelled = true; - - blockstmt("with", function() { - var t = state.tokens.next; - if (state.isStrict()) { - error("E010", state.tokens.curr); - } else if (!state.option.withstmt) { - warning("W085", state.tokens.curr); + // window.setTimeout/setInterval + } else if (p[0] && p[0].id === "(string)" && + left.value === "." && + left.left.value === "window" && + (left.right === "setTimeout" || + left.right === "setInterval")) { + warning("W066", left); + addEvalCode(left, p[0]); + } + } + if (!isTypicalCallExpression(left)) { + warning("W067", that); + } } - advance("("); - expression(0); - advance(")", t); - block(true, true); + that.left = left; + return that; + }, 155, true).exps = true; - return this; - }); + function peekThroughParens(parens) { + var pn = state.tokens.next; + var i = -1; + var pn1; - blockstmt("switch", function() { - var t = state.tokens.next; - var g = false; - var noindent = false; + do { + if (pn.value === "(") { + parens += 1; + } else if (pn.value === ")") { + parens -= 1; + } - state.funct["(breakage)"] += 1; - advance("("); - checkCondAssignment(expression(0)); - advance(")", t); - t = state.tokens.next; - advance("{"); + i += 1; + pn1 = pn; + pn = peek(i); + } while (!(parens === 0 && pn1.value === ")") && pn.type !== "(end)"); - if (state.tokens.next.from === indent) - noindent = true; + return pn; + } - if (!noindent) - indent += state.option.indent; + prefix("(", function(context, rbp) { + var ret, triggerFnExpr, first, last; + var opening = state.tokens.curr; + var preceeding = state.tokens.prev; + var isNecessary = !state.option.singleGroups; + var pn = peekThroughParens(1); - this.cases = []; + if (state.tokens.next.id === "function") { + triggerFnExpr = state.tokens.next.immed = true; + } - for (;;) { - switch (state.tokens.next.id) { - case "case": - switch (state.funct["(verb)"]) { - case "yield": - case "break": - case "case": - case "continue": - case "return": - case "switch": - case "throw": - break; - default: - // You can tell JSHint that you don't use break intentionally by - // adding a comment /* falls through */ on a line just before - // the next `case`. - if (!state.tokens.curr.caseFallsThrough) { - warning("W086", state.tokens.curr, "case"); - } - } + // If the balanced grouping operator is followed by a "fat arrow", the + // current token marks the beginning of a "fat arrow" function and parsing + // should proceed accordingly. + if (pn.value === "=>") { + pn.funct = doFunction(context, { type: "arrow", parsedOpening: true }); + return pn; + } - advance("case"); - this.cases.push(expression(0)); - increaseComplexityCount(); - g = true; - advance(":"); - state.funct["(verb)"] = "case"; - break; - case "default": - switch (state.funct["(verb)"]) { - case "yield": - case "break": - case "continue": - case "return": - case "throw": - break; - default: - // Do not display a warning if 'default' is the first statement or if - // there is a special /* falls through */ comment. - if (this.cases.length) { - if (!state.tokens.curr.caseFallsThrough) { - warning("W086", state.tokens.curr, "default"); - } - } - } + // The ECMA262 grammar requires an expression between the "opening + // parenthesis" and "close parenthesis" tokens of the grouping operator. + // However, the "ignore" directive is commonly used to inject values that + // are not included in the token stream. For example: + // + // return ( + // /*jshint ignore:start */ + //
      + // /*jshint ignore:end */ + // ); + // + // The "empty" grouping operator is permitted in order to tolerate this + // pattern. + if (state.tokens.next.id === ")") { + advance(")"); + return; + } - advance("default"); - g = true; - advance(":"); - break; - case "}": - if (!noindent) - indent -= state.option.indent; + ret = expression(context, 0); - advance("}", t); - state.funct["(breakage)"] -= 1; - state.funct["(verb)"] = undefined; - return; - case "(end)": - error("E023", state.tokens.next, "}"); - return; - default: - indent += state.option.indent; - if (g) { - switch (state.tokens.curr.id) { - case ",": - error("E040"); - return; - case ":": - g = false; - statements(); - break; - default: - error("E025", state.tokens.curr); - return; - } - } else { - if (state.tokens.curr.id === ":") { - advance(":"); - error("E024", state.tokens.curr, ":"); - statements(); - } else { - error("E021", state.tokens.next, "case", state.tokens.next.value); - return; - } - } - indent -= state.option.indent; - } + advance(")", this); + + if (!ret) { + return; } - return this; - }).labelled = true; - stmt("debugger", function() { - if (!state.option.debug) { - warning("W087", this); + ret.paren = true; + + if (state.option.immed && ret && ret.id === "function") { + if (state.tokens.next.id !== "(" && + state.tokens.next.id !== "." && state.tokens.next.id !== "[") { + warning("W068", this); + } } - return this; - }).exps = true; - (function() { - var x = stmt("do", function() { - state.funct["(breakage)"] += 1; - state.funct["(loopage)"] += 1; - increaseComplexityCount(); + if (ret.id === ",") { + first = ret.left; + while (first.id === ",") { + first = first.left; + } - this.first = block(true, true); - advance("while"); - var t = state.tokens.next; - advance("("); - checkCondAssignment(expression(0)); - advance(")", t); - state.funct["(breakage)"] -= 1; - state.funct["(loopage)"] -= 1; - return this; - }); - x.labelled = true; - x.exps = true; - }()); + last = ret.right; + } else { + first = last = ret; - blockstmt("for", function() { - var s, t = state.tokens.next; - var letscope = false; - var foreachtok = null; + if (!isNecessary) { + // async functions are identified after parsing due to the complexity + // of disambiguating the `async` keyword. + if (!triggerFnExpr) { + triggerFnExpr = ret.id === "async"; + } - if (t.value === "each") { - foreachtok = t; - advance("each"); - if (!state.inMoz()) { - warning("W118", state.tokens.curr, "for each"); + isNecessary = + // Used to distinguish from an ExpressionStatement which may not + // begin with the `{` and `function` tokens + (opening.beginsStmt && (ret.id === "{" || triggerFnExpr)) || + // Used to signal that a function expression is being supplied to + // some other operator. + (triggerFnExpr && + // For parenthesis wrapping a function expression to be considered + // necessary, the grouping operator should be the left-hand-side of + // some other operator--either within the parenthesis or directly + // following them. + (!isEndOfExpr() || state.tokens.prev.id !== "}")) || + // Used to demarcate an arrow function as the left-hand side of some + // operator. + (ret.id === "=>" && !isEndOfExpr()) || + // Used as the return value of a single-statement arrow function + (ret.id === "{" && preceeding.id === "=>") || + // Used to cover a unary expression as the left-hand side of the + // exponentiation operator + (beginsUnaryExpression(ret) && state.tokens.next.id === "**") || + // Used to cover a logical operator as the right-hand side of the + // nullish coalescing operator + (preceeding.id === "??" && (ret.id === "&&" || ret.id === "||")) || + // Used to delineate an integer number literal from a dereferencing + // punctuator (otherwise interpreted as a decimal point) + (ret.type === "(number)" && + checkPunctuator(pn, ".") && /^\d+$/.test(ret.value)) || + // Used to wrap object destructuring assignment + (opening.beginsStmt && ret.id === "=" && ret.left.id === "{") || + // Used to allow optional chaining with other language features which + // are otherwise restricted. + (ret.id === "?." && + (preceeding.id === "new" || state.tokens.next.type === "(template)")); } } - increaseComplexityCount(); - advance("("); + // The operator may be necessary to override the default binding power of + // neighboring operators (whenever there is an operator in use within the + // first expression *or* the current group contains multiple expressions) + if (!isNecessary && (isOperator(first) || first !== last)) { + isNecessary = + (rbp > first.lbp) || + (rbp > 0 && rbp === first.lbp) || + (!isEndOfExpr() && last.rbp < state.tokens.next.lbp); + } - // what kind of for(…) statement it is? for(…of…)? for(…in…)? for(…;…;…)? - var nextop; // contains the token of the "in" or "of" operator - var i = 0; - var inof = ["in", "of"]; - var level = 0; // BindingPattern "level" --- level 0 === no BindingPattern - var comma; // First comma punctuator at level 0 - var initializer; // First initializer at level 0 + if (!isNecessary) { + warning("W126", opening); + } - // If initial token is a BindingPattern, count it as such. - if (checkPunctuators(state.tokens.next, ["{", "["])) ++level; - do { - nextop = peek(i); - ++i; - if (checkPunctuators(nextop, ["{", "["])) ++level; - else if (checkPunctuators(nextop, ["}", "]"])) --level; - if (level < 0) break; - if (level === 0) { - if (!comma && checkPunctuator(nextop, ",")) comma = nextop; - else if (!initializer && checkPunctuator(nextop, "=")) initializer = nextop; - } - } while (level > 0 || !_.contains(inof, nextop.value) && nextop.value !== ";" && - nextop.type !== "(end)"); // Is this a JSCS bug? This looks really weird. + return ret; + }); - // if we're in a for (… in|of …) statement - if (_.contains(inof, nextop.value)) { - if (!state.inES6() && nextop.value === "of") { - warning("W104", nextop, "for of", "6"); - } + application("=>").rbp = 161; - var ok = !(initializer || comma); - if (initializer) { - error("W133", comma, nextop.value, "initializer is forbidden"); - } + infix("[", function(context, left, that) { + var e, s, canUseDot; - if (comma) { - error("W133", comma, nextop.value, "more than one ForBinding"); - } + if (state.option.asi && checkPunctuators(state.tokens.prev, [")", "]"]) && + !sameLine(state.tokens.prev, state.tokens.curr)) { + warning("W014", state.tokens.curr, state.tokens.curr.id); + } - if (state.tokens.next.id === "var") { - advance("var"); - state.tokens.curr.fud({ prefix: true }); - } else if (state.tokens.next.id === "let" || state.tokens.next.id === "const") { - advance(state.tokens.next.id); - // create a new block scope - letscope = true; - state.funct["(scope)"].stack(); - state.tokens.curr.fud({ prefix: true }); - } else { - // Parse as a var statement, with implied bindings. Ignore errors if an error - // was already reported - Object.create(varstatement).fud({ prefix: true, implied: "for", ignore: !ok }); + e = expression(context & ~prodParams.noin, 0); + + if (e && e.type === "(string)") { + if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) { + if (isGlobalEval(left, state)) { + warning("W061"); + } } - advance(nextop.value); - expression(20); - advance(")", t); - if (nextop.value === "in" && state.option.forin) { - state.forinifcheckneeded = true; + countMember(e.value); + if (!state.option.sub && reg.identifier.test(e.value)) { + s = state.syntax[e.value]; - if (state.forinifchecks === undefined) { - state.forinifchecks = []; + if (s) { + canUseDot = !isReserved(context, s); + } else { + // This branch exists to preserve legacy behavior with version 2.9.5 + // and earlier. In those releases, `eval` and `arguments` were + // incorrectly interpreted as reserved keywords, so Member + // Expressions such as `object["eval"]` did not trigger warning W069. + // + // TODO: Remove in JSHint 3 + canUseDot = e.value !== "eval" && e.value !== "arguments"; } - // Push a new for-in-if check onto the stack. The type will be modified - // when the loop's body is parsed and a suitable if statement exists. - state.forinifchecks.push({ - type: "(none)" - }); + if (canUseDot) { + warning("W069", state.tokens.prev, e.value); + } } + } + advance("]", that); - state.funct["(breakage)"] += 1; - state.funct["(loopage)"] += 1; - - s = block(true, true); + if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") { + warning("W001"); + } - if (nextop.value === "in" && state.option.forin) { - if (state.forinifchecks && state.forinifchecks.length > 0) { - var check = state.forinifchecks.pop(); + that.left = left; + that.right = e; + return that; + }, 160, true); - if (// No if statement or not the first statement in loop body - s && s.length > 0 && (typeof s[0] !== "object" || s[0].value !== "if") || - // Positive if statement is not the only one in loop body - check.type === "(positive)" && s.length > 1 || - // Negative if statement but no continue - check.type === "(negative)") { - warning("W089", this); - } - } + function comprehensiveArrayExpression(context) { + var res = {}; + res.exps = true; + state.funct["(comparray)"].stack(); - // Reset the flag in case no if statement was contained in the loop body - state.forinifcheckneeded = false; + // Handle reversed for expressions, used in spidermonkey + var reversed = false; + if (state.tokens.next.value !== "for") { + reversed = true; + if (!state.inMoz()) { + warning("W116", state.tokens.next, "for", state.tokens.next.value); } + state.funct["(comparray)"].setState("use"); + res.right = expression(context, 10); + } - state.funct["(breakage)"] -= 1; - state.funct["(loopage)"] -= 1; + advance("for"); + if (state.tokens.next.value === "each") { + advance("each"); + if (!state.inMoz()) { + warning("W118", state.tokens.curr, "for each"); + } + } + advance("("); + state.funct["(comparray)"].setState("define"); + res.left = expression(context, 130); + if (_.includes(["in", "of"], state.tokens.next.value)) { + advance(); } else { - if (foreachtok) { - error("E045", foreachtok); + /* istanbul ignore next */ + error("E045", state.tokens.curr); + } + state.funct["(comparray)"].setState("generate"); + expression(context, 10); + + advance(")"); + if (state.tokens.next.value === "if") { + advance("if"); + advance("("); + state.funct["(comparray)"].setState("filter"); + expression(context, 10); + advance(")"); + } + + if (!reversed) { + state.funct["(comparray)"].setState("use"); + res.right = expression(context, 10); + } + + advance("]"); + state.funct["(comparray)"].unstack(); + return res; + } + + prefix("[", function(context) { + var blocktype = lookupBlockType(); + if (blocktype.isCompArray) { + if (!state.option.esnext && !state.inMoz()) { + warning("W118", state.tokens.curr, "array comprehension"); } - if (state.tokens.next.id !== ";") { - if (state.tokens.next.id === "var") { - advance("var"); - state.tokens.curr.fud(); - } else if (state.tokens.next.id === "let") { - advance("let"); - // create a new block scope - letscope = true; - state.funct["(scope)"].stack(); - state.tokens.curr.fud(); - } else { - for (;;) { - expression(0, "for"); - if (state.tokens.next.id !== ",") { - break; - } - comma(); + return comprehensiveArrayExpression(context); + } else if (blocktype.isDestAssign) { + this.destructAssign = destructuringPattern(context, { + openingParsed: true, + assignment: true + }); + return this; + } + var b = !sameLine(state.tokens.curr, state.tokens.next); + this.first = []; + if (b) { + indent += state.option.indent; + if (state.tokens.next.from === indent + state.option.indent) { + /* istanbul ignore next */ + indent += state.option.indent; + } + } + while (state.tokens.next.id !== "(end)") { + while (state.tokens.next.id === ",") { + if (!state.option.elision) { + if (!state.inES5()) { + // Maintain compat with old options --- ES5 mode without + // elision=true will warn once per comma + warning("W070"); + } else { + warning("W128"); + do { + advance(","); + } while (state.tokens.next.id === ","); + continue; } } + advance(","); } - nolinebreak(state.tokens.curr); - advance(";"); - // start loopage after the first ; as the next two expressions are executed - // on every loop - state.funct["(loopage)"] += 1; - if (state.tokens.next.id !== ";") { - checkCondAssignment(expression(0)); - } - nolinebreak(state.tokens.curr); - advance(";"); - if (state.tokens.next.id === ";") { - error("E021", state.tokens.next, ")", ";"); + if (state.tokens.next.id === "]") { + break; } - if (state.tokens.next.id !== ")") { - for (;;) { - expression(0, "for"); - if (state.tokens.next.id !== ",") { - break; - } - comma(); + + spreadrest("spread"); + + this.first.push(expression(context, 10)); + if (state.tokens.next.id === ",") { + advance(","); + checkComma({ allowTrailing: true }); + if (state.tokens.next.id === "]" && !state.inES5()) { + warning("W070", state.tokens.curr); + break; } + } else { + if (state.option.trailingcomma && state.inES5()) { + warningAt("W140", state.tokens.curr.line, state.tokens.curr.character); + } + break; } - advance(")", t); - state.funct["(breakage)"] += 1; - block(true, true); - state.funct["(breakage)"] -= 1; - state.funct["(loopage)"] -= 1; - } - // unstack loop blockscope - if (letscope) { - state.funct["(scope)"].unstack(); + if (b) { + indent -= state.option.indent; } + advance("]", this); return this; - }).labelled = true; + }); - stmt("break", function() { - var v = state.tokens.next.value; + function isMethod() { + return !!state.funct["(method)"]; + } - if (!state.option.asi) - nolinebreak(this); + /** + * Retrieve the value of the next token if it is a valid LiteralPropertyName + * and optionally advance the parser. + * + * @param {number} context - the parsing context; see `prod-params.js` for + * more information + * + * @returns {string|undefined} - the value of the identifier, if present + */ + function propertyName(context) { + var id = optionalidentifier(context, true); - if (state.tokens.next.id !== ";" && !state.tokens.next.reach && - state.tokens.curr.line === startLine(state.tokens.next)) { - if (!state.funct["(scope)"].funct.hasBreakLabel(v)) { - warning("W090", state.tokens.next, v); + if (!id) { + if (state.tokens.next.id === "(string)") { + id = state.tokens.next.value; + advance(); + } else if (state.tokens.next.id === "(number)") { + id = state.tokens.next.value.toString(); + advance(); } - this.first = state.tokens.next; - advance(); - } else { - if (state.funct["(breakage)"] === 0) - warning("W052", state.tokens.next, this.value); } - reachable(this); + if (id === "hasOwnProperty") { + warning("W001"); + } - return this; - }).exps = true; + return id; + } + /** + * @param {Number} context The parsing context + * @param {Object} [options] + * @param {token} [options.loneArg] The argument to the function in cases + * where it was defined using the + * single-argument shorthand. + * @param {bool} [options.parsedOpening] Whether the opening parenthesis has + * already been parsed. + * + * @returns {{ arity: number, params: Array., isSimple: boolean }} + */ + function functionparams(context, options) { + var next; + var paramsIds = []; + var ident; + var tokens = []; + var t; + var pastDefault = false; + var pastRest = false; + var arity = 0; + var loneArg = options && options.loneArg; + var hasDestructuring = false; - stmt("continue", function() { - var v = state.tokens.next.value; + if (loneArg && loneArg.identifier === true) { + state.funct["(scope)"].addParam(loneArg.value, loneArg); + return { arity: 1, params: [ loneArg.value ], isSimple: true }; + } - if (state.funct["(breakage)"] === 0) - warning("W052", state.tokens.next, this.value); - if (!state.funct["(loopage)"]) - warning("W052", state.tokens.next, this.value); + next = state.tokens.next; - if (!state.option.asi) - nolinebreak(this); + if (!options || !options.parsedOpening) { + advance("("); + } - if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { - if (state.tokens.curr.line === startLine(state.tokens.next)) { - if (!state.funct["(scope)"].funct.hasBreakLabel(v)) { - warning("W090", state.tokens.next, v); - } - this.first = state.tokens.next; - advance(); - } + if (state.tokens.next.id === ")") { + advance(")"); + return; } - reachable(this); + function addParam(addParamArgs) { + state.funct["(scope)"].addParam.apply(state.funct["(scope)"], addParamArgs); + } - return this; - }).exps = true; + for (;;) { + arity++; + // are added to the param scope + var currentParams = []; + pastRest = spreadrest("rest"); - stmt("return", function() { - if (this.line === startLine(state.tokens.next)) { - if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { - this.first = expression(0); + if (_.includes(["{", "["], state.tokens.next.id)) { + hasDestructuring = true; + tokens = destructuringPattern(context); + for (t in tokens) { + t = tokens[t]; + if (t.id) { + paramsIds.push(t.id); + currentParams.push([t.id, t.token]); + } + } + } else { + ident = identifier(context); - if (this.first && - this.first.type === "(punctuator)" && this.first.value === "=" && - !this.first.paren && !state.option.boss) { - warningAt("W093", this.first.line, this.first.character); + if (ident) { + paramsIds.push(ident); + currentParams.push([ident, state.tokens.curr]); + } else { + // Skip invalid parameter. + while (!checkPunctuators(state.tokens.next, [",", ")"])) advance(); } } - } else { - if (state.tokens.next.type === "(punctuator)" && - ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) { - nolinebreak(this); // always warn (Line breaking error) - } - } - reachable(this); + // It is valid to have a regular argument after a default argument + // since undefined can be used for missing parameters. Still warn as it is + // a possible code smell. + if (pastDefault) { + if (state.tokens.next.id !== "=") { + error("W138", state.tokens.curr); + } + } + if (state.tokens.next.id === "=") { + if (!state.inES6()) { + warning("W119", state.tokens.next, "default parameters", "6"); + } - return this; - }).exps = true; + if (pastRest) { + error("E062", state.tokens.next); + } - (function(x) { - x.exps = true; - x.lbp = 25; - }(prefix("yield", function() { - var prev = state.tokens.prev; - if (state.inES6(true) && !state.funct["(generator)"]) { - // If it's a yield within a catch clause inside a generator then that's ok - if (!("(catch)" === state.funct["(name)"] && state.funct["(context)"]["(generator)"])) { - error("E046", state.tokens.curr, "yield"); + advance("="); + pastDefault = true; + expression(context, 10); } - } else if (!state.inES6()) { - warning("W104", state.tokens.curr, "yield", "6"); - } - state.funct["(generator)"] = "yielded"; - var delegatingYield = false; - - if (state.tokens.next.value === "*") { - delegatingYield = true; - advance("*"); - } - - if (this.line === startLine(state.tokens.next) || !state.inMoz()) { - if (delegatingYield || - (state.tokens.next.id !== ";" && !state.option.asi && - !state.tokens.next.reach && state.tokens.next.nud)) { - - nobreaknonadjacent(state.tokens.curr, state.tokens.next); - this.first = expression(10); - if (this.first.type === "(punctuator)" && this.first.value === "=" && - !this.first.paren && !state.option.boss) { - warningAt("W093", this.first.line, this.first.character); + // now we have evaluated the default expression, add the variable to the param scope + currentParams.forEach(addParam); + if (state.tokens.next.id === ",") { + if (pastRest) { + warning("W131", state.tokens.next); } + advance(","); + checkComma({ allowTrailing: true }); } - if (state.inMoz() && state.tokens.next.id !== ")" && - (prev.lbp > 30 || (!prev.assign && !isEndOfExpr()) || prev.id === "yield")) { - error("E050", this); + if (state.tokens.next.id === ")") { + if (state.tokens.curr.id === "," && !state.inES8()) { + warning("W119", state.tokens.curr, "Trailing comma in function parameters", "8"); + } + + advance(")", next); + return { + arity: arity, + params: paramsIds, + isSimple: !hasDestructuring && !pastRest && !pastDefault + }; } - } else if (!state.option.asi) { - nolinebreak(this); // always warn (Line breaking error) } - return this; - }))); - - - stmt("throw", function() { - nolinebreak(this); - this.first = expression(20); + } - reachable(this); + /** + * Factory function for creating objects used to track statistics of function + * literals. + * + * @param {string} name - the identifier name to associate with the function + * @param {object} [token] - token responsible for creating the function + * object + * @param {object} [overwrites] - a collection of properties that should + * override the corresponding default value of + * the new "functor" object + */ + function functor(name, token, overwrites) { + var funct = { + "(name)" : name, + "(breakage)" : 0, + "(loopage)" : 0, + // The strictness of the function body is tracked via a dedicated + // property (as opposed to via the global `state` object) so that the + // value can be referenced after the body has been fully parsed (i.e. + // when validating the identifier used in function declarations and + // function expressions). + "(isStrict)" : "unknown", - return this; - }).exps = true; + "(global)" : false, - stmt("import", function() { - if (!state.inES6()) { - warning("W119", state.tokens.curr, "import", "6"); - } + "(line)" : null, + "(character)" : null, + "(metrics)" : null, + "(statement)" : null, + "(context)" : null, + "(scope)" : null, + "(comparray)" : null, + "(yielded)" : null, + "(arrow)" : null, + "(async)" : null, + "(params)" : null + }; - if (state.tokens.next.type === "(string)") { - // ModuleSpecifier :: StringLiteral - advance("(string)"); - return this; + if (token) { + _.extend(funct, { + "(line)" : token.line, + "(character)": token.character, + "(metrics)" : createMetrics(token) + }); } - if (state.tokens.next.identifier) { - // ImportClause :: ImportedDefaultBinding - this.name = identifier(); - // Import bindings are immutable (see ES6 8.1.1.5.5) - state.funct["(scope)"].addlabel(this.name, { - type: "const", - token: state.tokens.curr }); + _.extend(funct, overwrites); - if (state.tokens.next.value === ",") { - // ImportClause :: ImportedDefaultBinding , NameSpaceImport - // ImportClause :: ImportedDefaultBinding , NamedImports - advance(","); - // At this point, we intentionally fall through to continue matching - // either NameSpaceImport or NamedImports. - // Discussion: - // https://github.com/jshint/jshint/pull/2144#discussion_r23978406 - } else { - advance("from"); - advance("(string)"); - return this; - } + if (funct["(context)"]) { + funct["(scope)"] = funct["(context)"]["(scope)"]; + funct["(comparray)"] = funct["(context)"]["(comparray)"]; } - if (state.tokens.next.id === "*") { - // ImportClause :: NameSpaceImport - advance("*"); - advance("as"); - if (state.tokens.next.identifier) { - this.name = identifier(); - // Import bindings are immutable (see ES6 8.1.1.5.5) - state.funct["(scope)"].addlabel(this.name, { - type: "const", - token: state.tokens.curr }); - } - } else { - // ImportClause :: NamedImports - advance("{"); - for (;;) { - if (state.tokens.next.value === "}") { - advance("}"); - break; - } - var importName; - if (state.tokens.next.type === "default") { - importName = "default"; - advance("default"); - } else { - importName = identifier(); - } - if (state.tokens.next.value === "as") { - advance("as"); - importName = identifier(); - } + return funct; + } - // Import bindings are immutable (see ES6 8.1.1.5.5) - state.funct["(scope)"].addlabel(importName, { - type: "const", - token: state.tokens.curr }); + /** + * Determine if the parser has begun parsing executable code. + * + * @param {Token} funct - The current "functor" token + * + * @returns {boolean} + */ + function hasParsedCode(funct) { + return funct["(global)"] && !funct["(verb)"]; + } - if (state.tokens.next.value === ",") { - advance(","); - } else if (state.tokens.next.value === "}") { - advance("}"); - break; + /** + * This function is used as both a null-denotation method *and* a + * left-denotation method, meaning the first parameter is overloaded. + */ + function doTemplateLiteral(context, leftOrRbp) { + // ASSERT: this.type === "(template)" + // jshint validthis: true + var ctx = this.context; + var noSubst = this.noSubst; + var depth = this.depth; + var left = typeof leftOrRbp === "number" ? null : leftOrRbp; + + if (!noSubst) { + while (!end()) { + if (!state.tokens.next.template || state.tokens.next.depth > depth) { + expression(context, 0); // should probably have different rbp? } else { - error("E024", state.tokens.next, state.tokens.next.value); - break; + // skip template start / middle + advance(); } } } - // FromClause - advance("from"); - advance("(string)"); - return this; - }).exps = true; - - stmt("export", function() { - var ok = true; - var token; - var identifier; + return { + id: "(template)", + type: "(template)", + tag: left + }; - if (!state.inES6()) { - warning("W119", state.tokens.curr, "export", "6"); - ok = false; + function end() { + if (state.tokens.curr.template && state.tokens.curr.tail && + state.tokens.curr.context === ctx) { + /* istanbul ignore next */ + return true; + } + var complete = (state.tokens.next.template && state.tokens.next.tail && + state.tokens.next.context === ctx); + if (complete) advance(); + return complete || state.tokens.next.isUnclosed; } + } - if (!state.funct["(scope)"].block.isGlobal()) { - error("E053", state.tokens.curr); - ok = false; + /** + * Parse a function literal. + * + * @param {Number} context The parsing context + * @param {Object} [options] + * @param {string} [options.name] The identifier belonging to the function (if + * any) + * @param {token} [options.statement] The statement that triggered creation + * of the current function. + * @param {string} [options.type] If specified, either "generator" or "arrow" + * @param {token} [options.loneArg] The argument to the function in cases + * where it was defined using the + * single-argument shorthand + * @param {bool} [options.parsedOpening] Whether the opening parenthesis has + * already been parsed + * @param {string} [options.classExprBinding] Define a function with this + * identifier in the new function's + * scope, mimicking the bahavior of + * class expression names within + * the body of member functions. + */ + function doFunction(context, options) { + var f, token, name, statement, classExprBinding, isGenerator, isArrow, + isMethod, ignoreLoopFunc; + var oldOption = state.option; + var oldIgnored = state.ignored; + var isAsync = context & prodParams.preAsync; + + if (options) { + name = options.name; + statement = options.statement; + classExprBinding = options.classExprBinding; + isGenerator = options.type === "generator"; + isArrow = options.type === "arrow"; + isMethod = options.isMethod; + ignoreLoopFunc = options.ignoreLoopFunc; } - if (state.tokens.next.value === "*") { - // ExportDeclaration :: export * FromClause - advance("*"); - advance("from"); - advance("(string)"); - return this; + context &= ~prodParams.noin; + context &= ~prodParams.tryClause; + + if (isAsync) { + context |= prodParams.async; + } else { + context &= ~prodParams.async; } - if (state.tokens.next.type === "default") { - // ExportDeclaration :: - // export default [lookahead  { function, class }] AssignmentExpression[In] ; - // export default HoistableDeclaration - // export default ClassDeclaration - state.nameStack.set(state.tokens.next); - advance("default"); - var exportType = state.tokens.next.id; - if (exportType === "function" || exportType === "class") { - this.block = true; - } + if (isGenerator) { + context |= prodParams.yield; + } else if (!isArrow) { + context &= ~prodParams.yield; + } + context &= ~prodParams.preAsync; - token = peek(); + state.option = Object.create(state.option); + state.ignored = Object.create(state.ignored); - expression(10); + state.funct = functor(name || state.nameStack.infer(), state.tokens.next, { + "(statement)": statement, + "(context)": state.funct, + "(arrow)": isArrow, + "(method)": isMethod, + "(async)": isAsync + }); - identifier = token.value; + f = state.funct; + token = state.tokens.curr; - if (this.block) { - state.funct["(scope)"].addlabel(identifier, { - type: exportType, - token: token }); + functions.push(state.funct); - state.funct["(scope)"].setExported(identifier, token); - } + // So that the function is available to itself and referencing itself is not + // seen as a closure, add the function name to a new scope, but do not + // test for unused (unused: false) + // it is a new block scope so that params can override it, it can be block scoped + // but declarations inside the function don't cause already declared error + state.funct["(scope)"].stack("functionouter"); + var internallyAccessibleName = !isMethod && (name || classExprBinding); + if (internallyAccessibleName) { + state.funct["(scope)"].block.add(internallyAccessibleName, + classExprBinding ? "class" : "function", state.tokens.curr, false); + } - return this; + if (!isArrow) { + state.funct["(scope)"].funct.add("arguments", "var", token, false); } - if (state.tokens.next.value === "{") { - // ExportDeclaration :: export ExportClause - advance("{"); - var exportedTokens = []; - for (;;) { - if (!state.tokens.next.identifier) { - error("E030", state.tokens.next, state.tokens.next.value); - } - advance(); + // create the param scope (params added in functionparams) + state.funct["(scope)"].stack("functionparams"); - exportedTokens.push(state.tokens.curr); + var paramsInfo = functionparams(context, options); - if (state.tokens.next.value === "as") { - advance("as"); - if (!state.tokens.next.identifier) { - error("E030", state.tokens.next, state.tokens.next.value); - } - advance(); - } + if (paramsInfo) { + state.funct["(params)"] = paramsInfo.params; + state.funct["(hasSimpleParams)"] = paramsInfo.isSimple; + state.funct["(metrics)"].arity = paramsInfo.arity; + state.funct["(metrics)"].verifyMaxParametersPerFunction(); + } else { + state.funct["(params)"] = []; + state.funct["(metrics)"].arity = 0; + state.funct["(hasSimpleParams)"] = true; + } - if (state.tokens.next.value === ",") { - advance(","); - } else if (state.tokens.next.value === "}") { - advance("}"); - break; - } else { - error("E024", state.tokens.next, state.tokens.next.value); - break; - } + if (isArrow) { + context &= ~prodParams.yield; + + if (!state.inES6(true)) { + warning("W119", state.tokens.curr, "arrow function syntax (=>)", "6"); } - if (state.tokens.next.value === "from") { - // ExportDeclaration :: export ExportClause FromClause - advance("from"); - advance("(string)"); - } else if (ok) { - exportedTokens.forEach(function(token) { - state.funct["(scope)"].setExported(token.value, token); - }); + + if (!options.loneArg) { + advance("=>"); } - return this; } - if (state.tokens.next.id === "var") { - // ExportDeclaration :: export VariableStatement - advance("var"); - state.tokens.curr.fud({ inexport:true }); - } else if (state.tokens.next.id === "let") { - // ExportDeclaration :: export VariableStatement - advance("let"); - state.tokens.curr.fud({ inexport:true }); - } else if (state.tokens.next.id === "const") { - // ExportDeclaration :: export VariableStatement - advance("const"); - state.tokens.curr.fud({ inexport:true }); - } else if (state.tokens.next.id === "function") { - // ExportDeclaration :: export Declaration - this.block = true; - advance("function"); - state.syntax["function"].fud({ inexport:true }); - } else if (state.tokens.next.id === "class") { - // ExportDeclaration :: export Declaration - this.block = true; - advance("class"); - var classNameToken = state.tokens.next; - state.syntax["class"].fud(); - state.funct["(scope)"].setExported(classNameToken.value, classNameToken); - } else { - error("E024", state.tokens.next, state.tokens.next.value); + block(context, false, true, true, isArrow); + + if (!state.option.noyield && isGenerator && !state.funct["(yielded)"]) { + warning("W124", state.tokens.curr); } - return this; - }).exps = true; + state.funct["(metrics)"].verifyMaxStatementsPerFunction(); + state.funct["(metrics)"].verifyMaxComplexityPerFunction(); + state.funct["(unusedOption)"] = state.option.unused; + state.option = oldOption; + state.ignored = oldIgnored; + state.funct["(last)"] = state.tokens.curr.line; + state.funct["(lastcharacter)"] = state.tokens.curr.character; - // Future Reserved Words + // unstack the params scope + state.funct["(scope)"].unstack(); // also does usage and label checks - FutureReservedWord("abstract"); - FutureReservedWord("boolean"); - FutureReservedWord("byte"); - FutureReservedWord("char"); - FutureReservedWord("class", { es5: true, nud: classdef }); - FutureReservedWord("double"); - FutureReservedWord("enum", { es5: true }); - FutureReservedWord("export", { es5: true }); - FutureReservedWord("extends", { es5: true }); - FutureReservedWord("final"); - FutureReservedWord("float"); - FutureReservedWord("goto"); - FutureReservedWord("implements", { es5: true, strictOnly: true }); - FutureReservedWord("import", { es5: true }); - FutureReservedWord("int"); - FutureReservedWord("interface", { es5: true, strictOnly: true }); - FutureReservedWord("long"); - FutureReservedWord("native"); - FutureReservedWord("package", { es5: true, strictOnly: true }); - FutureReservedWord("private", { es5: true, strictOnly: true }); - FutureReservedWord("protected", { es5: true, strictOnly: true }); - FutureReservedWord("public", { es5: true, strictOnly: true }); - FutureReservedWord("short"); - FutureReservedWord("static", { es5: true, strictOnly: true }); - FutureReservedWord("super", { es5: true }); - FutureReservedWord("synchronized"); - FutureReservedWord("transient"); - FutureReservedWord("volatile"); + // unstack the function outer stack + state.funct["(scope)"].unstack(); - // this function is used to determine whether a squarebracket or a curlybracket - // expression is a comprehension array, destructuring assignment or a json value. + state.funct = state.funct["(context)"]; - var lookupBlockType = function() { - var pn, pn1, prev; - var i = -1; - var bracketStack = 0; - var ret = {}; - if (checkPunctuators(state.tokens.curr, ["[", "{"])) { - bracketStack += 1; - } - do { - prev = i === -1 ? state.tokens.curr : pn; - pn = i === -1 ? state.tokens.next : peek(i); - pn1 = peek(i + 1); - i = i + 1; - if (checkPunctuators(pn, ["[", "{"])) { - bracketStack += 1; - } else if (checkPunctuators(pn, ["]", "}"])) { - bracketStack -= 1; - } - if (bracketStack === 1 && pn.identifier && pn.value === "for" && - !checkPunctuator(prev, ".")) { - ret.isCompArray = true; - ret.notJson = true; - break; - } - if (bracketStack === 0 && checkPunctuators(pn, ["}", "]"])) { - if (pn1.value === "=") { - ret.isDestAssign = true; - ret.notJson = true; - break; - } else if (pn1.value === ".") { - ret.notJson = true; - break; - } - } - if (checkPunctuator(pn, ";")) { - ret.isBlock = true; - ret.notJson = true; + if (!ignoreLoopFunc && !state.option.loopfunc && state.funct["(loopage)"]) { + // If the function we just parsed accesses any non-local variables + // trigger a warning. Otherwise, the function is safe even within + // a loop. + if (f["(outerMutables)"]) { + warning("W083", token, f["(outerMutables)"].join(", ")); } - } while (bracketStack > 0 && pn.id !== "(end)"); - return ret; - }; - - function saveProperty(props, name, tkn, isClass, isStatic) { - var msg = ["key", "class method", "static class method"]; - msg = msg[(isClass || false) + (isStatic || false)]; - if (tkn.identifier) { - name = tkn.value; - } - - if (props[name] && name !== "__proto__") { - warning("W075", state.tokens.next, msg, name); - } else { - props[name] = Object.create(null); } - props[name].basic = true; - props[name].basictkn = tkn; + return f; } - /** - * @param {string} accessorType - Either "get" or "set" - * @param {object} props - a collection of all properties of the object to - * which the current accessor is being assigned - * @param {object} tkn - the identifier token representing the accessor name - * @param {boolean} isClass - whether the accessor is part of an ES6 Class - * definition - * @param {boolean} isStatic - whether the accessor is a static method - */ - function saveAccessor(accessorType, props, name, tkn, isClass, isStatic) { - var flagName = accessorType === "get" ? "getterToken" : "setterToken"; - var msg = ""; + function createMetrics(functionStartToken) { + return { + statementCount: 0, + nestedBlockDepth: -1, + ComplexityCount: 1, + arity: 0, - if (isClass) { - if (isStatic) { - msg += "static "; - } - msg += accessorType + "ter method"; - } else { - msg = "key"; - } + verifyMaxStatementsPerFunction: function() { + if (state.option.maxstatements && + this.statementCount > state.option.maxstatements) { + warning("W071", functionStartToken, this.statementCount); + } + }, - state.tokens.curr.accessorType = accessorType; - state.nameStack.set(tkn); + verifyMaxParametersPerFunction: function() { + if (_.isNumber(state.option.maxparams) && + this.arity > state.option.maxparams) { + warning("W072", functionStartToken, this.arity); + } + }, - if (props[name]) { - if ((props[name].basic || props[name][flagName]) && name !== "__proto__") { - warning("W075", state.tokens.next, msg, name); + verifyMaxNestedBlockDepthPerFunction: function() { + if (state.option.maxdepth && + this.nestedBlockDepth > 0 && + this.nestedBlockDepth === state.option.maxdepth + 1) { + warning("W073", null, this.nestedBlockDepth); + } + }, + + verifyMaxComplexityPerFunction: function() { + var max = state.option.maxcomplexity; + var cc = this.ComplexityCount; + if (max && cc > max) { + warning("W074", functionStartToken, cc); + } } - } else { - props[name] = Object.create(null); - } + }; + } - props[name][flagName] = tkn; + function increaseComplexityCount() { + state.funct["(metrics)"].ComplexityCount += 1; } - function computedPropertyName() { - advance("["); - if (!state.inES6()) { - warning("W119", state.tokens.curr, "computed property names", "6"); + // Parse assignments that were found instead of conditionals. + // For example: if (a = 1) { ... } + + function checkCondAssignment(token) { + if (!token || token.paren) { + return; + } + + if (token.id === ",") { + checkCondAssignment(token.right); + return; + } + + switch (token.id) { + case "=": + case "+=": + case "-=": + case "*=": + case "%=": + case "&=": + case "|=": + case "^=": + case "/=": + if (!state.option.boss) { + warning("W084", token); + } } - var value = expression(10); - advance("]"); - return value; } /** - * Test whether a given token is a punctuator matching one of the specified values - * @param {Token} token - * @param {Array.} values - * @returns {boolean} + * Validate the properties defined within an object literal or class body. + * See the `saveAccessor` and `saveProperty` functions for more detail. + * + * @param {object} props - Collection of objects describing the properties + * encountered */ - function checkPunctuators(token, values) { - if (token.type === "(punctuator)") { - return _.contains(values, token.value); + function checkProperties(props) { + // Check for lonely setters if in the ES5 mode. + if (state.inES5()) { + for (var name in props) { + if (props[name] && props[name].setterToken && !props[name].getterToken && + !props[name].static) { + warning("W078", props[name].setterToken); + } + } } - return false; } - /** - * Test whether a given token is a punctuator matching the specified value - * @param {Token} token - * @param {string} value - * @returns {boolean} - */ - function checkPunctuator(token, value) { - return token.type === "(punctuator)" && token.value === value; + function metaProperty(context, name, c) { + if (checkPunctuator(state.tokens.next, ".")) { + var left = state.tokens.curr.id; + advance("."); + var id = identifier(context); + state.tokens.curr.isMetaProperty = true; + if (name !== id) { + error("E057", state.tokens.prev, left, id); + } else { + c(); + } + return state.tokens.curr; + } } - // Check whether this function has been reached for a destructuring assign with undeclared values - function destructuringAssignOrJsonValue() { - // lookup for the assignment (ECMAScript 6 only) - // if it has semicolons, it is a block, so go parse it as a block - // or it's not a block, but there are assignments, check for undeclared variables +//object literals + (function(x) { + x.nud = function(context) { + var b, f, i, params, t, isGeneratorMethod = false, nextVal; + var props = Object.create(null); // All properties, including accessors + var isAsyncMethod = false; - var block = lookupBlockType(); - if (block.notJson) { - if (!state.inES6() && block.isDestAssign) { - warning("W104", state.tokens.curr, "destructuring assignment", "6"); + b = !sameLine(state.tokens.curr, state.tokens.next); + if (b) { + indent += state.option.indent; + if (state.tokens.next.from === indent + state.option.indent) { + /* istanbul ignore next */ + indent += state.option.indent; + } } - statements(); - // otherwise parse json value - } else { - state.option.laxbreak = true; - state.jsonMode = true; - jsonValue(); - } - } - // array comprehension parsing function - // parses and defines the three states of the list comprehension in order - // to avoid defining global variables, but keeping them to the list comprehension scope - // only. The order of the states are as follows: - // * "use" which will be the returned iterative part of the list comprehension - // * "define" which will define the variables local to the list comprehension - // * "filter" which will help filter out values - - var arrayComprehension = function() { - var CompArray = function() { - this.mode = "use"; - this.variables = []; - }; - var _carrays = []; - var _current; - function declare(v) { - var l = _current.variables.filter(function(elt) { - // if it has, change its undef state - if (elt.value === v) { - elt.undef = false; - return v; - } - }).length; - return l !== 0; - } - function use(v) { - var l = _current.variables.filter(function(elt) { - // and if it has been defined - if (elt.value === v && !elt.undef) { - if (elt.unused === true) { - elt.unused = false; - } - return v; - } - }).length; - // otherwise we warn about it - return (l === 0); - } - return { stack: function() { - _current = new CompArray(); - _carrays.push(_current); - }, - unstack: function() { - _current.variables.filter(function(v) { - if (v.unused) - warning("W098", v.token, v.raw_text || v.value); - if (v.undef) - state.funct["(scope)"].block.use(v.value, v.token); + var blocktype = lookupBlockType(); + if (blocktype.isDestAssign) { + this.destructAssign = destructuringPattern(context, { + openingParsed: true, + assignment: true }); - _carrays.splice(-1, 1); - _current = _carrays[_carrays.length - 1]; - }, - setState: function(s) { - if (_.contains(["use", "define", "generate", "filter"], s)) - _current.mode = s; - }, - check: function(v) { - if (!_current) { - return; - } - // When we are in "use" state of the list comp, we enqueue that var - if (_current && _current.mode === "use") { - if (use(v)) { - _current.variables.push({ - funct: state.funct, - token: state.tokens.curr, - value: v, - undef: true, - unused: false - }); - } - return true; - // When we are in "define" state of the list comp, - } else if (_current && _current.mode === "define") { - // check if the variable has been used previously - if (!declare(v)) { - _current.variables.push({ - funct: state.funct, - token: state.tokens.curr, - value: v, - undef: false, - unused: true - }); - } - return true; - // When we are in the "generate" state of the list comp, - } else if (_current && _current.mode === "generate") { - state.funct["(scope)"].block.use(v, state.tokens.curr); - return true; - // When we are in "filter" state, - } else if (_current && _current.mode === "filter") { - // we check whether current variable has been declared - if (use(v)) { - // if not we warn about it - state.funct["(scope)"].block.use(v, state.tokens.curr); - } - return true; - } - return false; + return this; + } + state.inObjectBody = true; + for (;;) { + if (state.tokens.next.id === "}") { + break; } - }; - }; + nextVal = state.tokens.next.value; + if (state.tokens.next.identifier && + (peekIgnoreEOL().id === "," || peekIgnoreEOL().id === "}")) { + if (!state.inES6()) { + warning("W104", state.tokens.next, "object short notation", "6"); + } + t = expression(context, 10); + i = t && t.value; + if (t) { + saveProperty(props, i, t); + } - // Parse JSON + } else if (peek().id !== ":" && (nextVal === "get" || nextVal === "set")) { + advance(nextVal); - function jsonValue() { - function jsonObject() { - var o = {}, t = state.tokens.next; - advance("{"); - if (state.tokens.next.id !== "}") { - for (;;) { - if (state.tokens.next.id === "(end)") { - error("E026", state.tokens.next, t.line); - } else if (state.tokens.next.id === "}") { - warning("W094", state.tokens.curr); - break; - } else if (state.tokens.next.id === ",") { - error("E028", state.tokens.next); - } else if (state.tokens.next.id !== "(string)") { - warning("W095", state.tokens.next, state.tokens.next.value); + if (!state.inES5()) { + error("E034"); } - if (o[state.tokens.next.value] === true) { - warning("W075", state.tokens.next, "key", state.tokens.next.value); - } else if ((state.tokens.next.value === "__proto__" && - !state.option.proto) || (state.tokens.next.value === "__iterator__" && - !state.option.iterator)) { - warning("W096", state.tokens.next, state.tokens.next.value); + + if (state.tokens.next.id === "[") { + i = computedPropertyName(context); } else { - o[state.tokens.next.value] = true; + i = propertyName(context); + + // ES6 allows for get() {...} and set() {...} method + // definition shorthand syntax, so we don't produce an error + // if linting ECMAScript 6 code. + if (!i && !state.inES6()) { + error("E035"); + } } - advance(); - advance(":"); - jsonValue(); - if (state.tokens.next.id !== ",") { - break; + + // We don't want to save this getter unless it's an actual getter + // and not an ES6 concise method + if (i) { + saveAccessor(nextVal, props, i, state.tokens.curr); } - advance(","); - } - } - advance("}"); - } - function jsonArray() { - var t = state.tokens.next; - advance("["); - if (state.tokens.next.id !== "]") { - for (;;) { - if (state.tokens.next.id === "(end)") { - error("E027", state.tokens.next, t.line); - } else if (state.tokens.next.id === "]") { - warning("W094", state.tokens.curr); - break; - } else if (state.tokens.next.id === ",") { - error("E028", state.tokens.next); + t = state.tokens.next; + f = doFunction(context, { isMethod: true }); + params = f["(params)"]; + + // Don't warn about getter/setter pairs if this is an ES6 concise method + if (nextVal === "get" && i && params.length) { + warning("W076", t, params[0], i); + } else if (nextVal === "set" && i && f["(metrics)"].arity !== 1) { + warning("W077", t, i); } - jsonValue(); - if (state.tokens.next.id !== ",") { - break; + + } else if (spreadrest("spread")) { + if (!state.inES9()) { + warning("W119", state.tokens.next, "object spread property", "9"); } - advance(","); - } - } - advance("]"); - } - switch (state.tokens.next.id) { - case "{": - jsonObject(); - break; - case "[": - jsonArray(); - break; - case "true": - case "false": - case "null": - case "(number)": - case "(string)": - advance(); - break; - case "-": - advance("-"); - advance("(number)"); - break; - default: - error("E003", state.tokens.next); - } - } + expression(context, 10); + } else { + if (state.tokens.next.id === "async" && !checkPunctuators(peek(), ["(", ":"])) { + if (!state.inES8()) { + warning("W119", state.tokens.next, "async functions", "8"); + } - var escapeRegex = function(str) { - return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); - }; + isAsyncMethod = true; + advance(); - // The actual JSHINT function itself. - var itself = function(s, o, g) { - var i, k, x, reIgnoreStr, reIgnore; - var optionKeys; - var newOptionObj = {}; - var newIgnoredObj = {}; + nolinebreak(state.tokens.curr); + } else { + isAsyncMethod = false; + } - o = _.clone(o); - state.reset(); + if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") { + if (isAsyncMethod && !state.inES9()) { + warning("W119", state.tokens.next, "async generators", "9"); + } else if (!state.inES6()) { + warning("W104", state.tokens.next, "generator functions", "6"); + } - if (o && o.scope) { - JSHINT.scope = o.scope; - } else { - JSHINT.errors = []; - JSHINT.undefs = []; - JSHINT.internals = []; - JSHINT.blacklist = {}; - JSHINT.scope = "(main)"; - } + advance("*"); + isGeneratorMethod = true; + } else { + isGeneratorMethod = false; + } - predefined = Object.create(null); - combine(predefined, vars.ecmaIdentifiers[3]); - combine(predefined, vars.reservedVars); + if (state.tokens.next.id === "[") { + i = computedPropertyName(context); + state.nameStack.set(i); + } else { + state.nameStack.set(state.tokens.next); + i = propertyName(context); + saveProperty(props, i, state.tokens.next); - combine(predefined, g || {}); + if (typeof i !== "string") { + break; + } + } - declared = Object.create(null); - var exported = Object.create(null); // Variables that live outside the current file - - function each(obj, cb) { - if (!obj) - return; - - if (!Array.isArray(obj) && typeof obj === "object") - obj = Object.keys(obj); - - obj.forEach(cb); - } + if (state.tokens.next.value === "(") { + if (!state.inES6()) { + warning("W104", state.tokens.curr, "concise methods", "6"); + } - if (o) { - each(o.predef || null, function(item) { - var slice, prop; - - if (item[0] === "-") { - slice = item.slice(1); - JSHINT.blacklist[slice] = slice; - // remove from predefined if there - delete predefined[slice]; - } else { - prop = Object.getOwnPropertyDescriptor(o.predef, item); - predefined[item] = prop ? prop.value : false; + doFunction(isAsyncMethod ? context | prodParams.preAsync : context, { + isMethod: true, + type: isGeneratorMethod ? "generator" : null + }); + } else { + advance(":"); + expression(context, 10); + } } - }); - - each(o.exported || null, function(item) { - exported[item] = true; - }); - delete o.predef; - delete o.exported; + countMember(i); - optionKeys = Object.keys(o); - for (x = 0; x < optionKeys.length; x++) { - if (/^-W\d{3}$/g.test(optionKeys[x])) { - newIgnoredObj[optionKeys[x].slice(1)] = true; + if (state.tokens.next.id === ",") { + advance(","); + checkComma({ allowTrailing: true, property: true }); + if (state.tokens.next.id === ",") { + /* istanbul ignore next */ + warning("W070", state.tokens.curr); + } else if (state.tokens.next.id === "}" && !state.inES5()) { + warning("W070", state.tokens.curr); + } } else { - var optionKey = optionKeys[x]; - newOptionObj[optionKey] = o[optionKey]; - if ((optionKey === "esversion" && o[optionKey] === 5) || - (optionKey === "es5" && o[optionKey])) { - warning("I003"); + if (state.option.trailingcomma && state.inES5()) { + warningAt("W140", state.tokens.curr.line, state.tokens.curr.character); } - - if (optionKeys[x] === "newcap" && o[optionKey] === false) - newOptionObj["(explicitNewcap)"] = true; + break; } } - } + if (b) { + indent -= state.option.indent; + } + advance("}", this); - state.option = newOptionObj; - state.ignored = newIgnoredObj; + checkProperties(props); + state.inObjectBody = false; - state.option.indent = state.option.indent || 4; - state.option.maxerr = state.option.maxerr || 50; + return this; + }; + x.fud = function() { + /* istanbul ignore next */ + error("E036", state.tokens.curr); + }; + }(delim("{"))); - indent = 1; + function destructuringPattern(context, options) { + var isAssignment = options && options.assignment; - var scopeManagerInst = scopeManager(state, predefined, exported, declared); - scopeManagerInst.on("warning", function(ev) { - warning.apply(null, [ ev.code, ev.token].concat(ev.data)); - }); + context &= ~prodParams.noin; - scopeManagerInst.on("error", function(ev) { - error.apply(null, [ ev.code, ev.token ].concat(ev.data)); - }); + if (!state.inES6()) { + warning("W104", state.tokens.curr, + isAssignment ? "destructuring assignment" : "destructuring binding", "6"); + } - state.funct = functor("(global)", null, { - "(global)" : true, - "(scope)" : scopeManagerInst, - "(comparray)" : arrayComprehension(), - "(metrics)" : createMetrics(state.tokens.next) - }); + return destructuringPatternRecursive(context, options); + } - functions = [state.funct]; - urls = []; - stack = null; - member = {}; - membersOnly = null; - inblock = false; - lookahead = []; + function destructuringPatternRecursive(context, options) { + var ids, idx; + var identifiers = []; + var openingParsed = options && options.openingParsed; + var isAssignment = options && options.assignment; + var recursiveOptions = isAssignment ? { assignment: isAssignment } : null; + var firstToken = openingParsed ? state.tokens.curr : state.tokens.next; - if (!isString(s) && !Array.isArray(s)) { - errorAt("E004", 0); - return false; - } + var nextInnerDE = function() { + var ident; + if (checkPunctuators(state.tokens.next, ["[", "{"])) { + ids = destructuringPatternRecursive(context, recursiveOptions); + for (idx = 0; idx < ids.length; idx++) { + identifiers.push({ id: ids[idx].id, token: ids[idx].token }); + } + } else if (checkPunctuator(state.tokens.next, ",")) { + identifiers.push({ id: null, token: state.tokens.curr }); + } else if (checkPunctuator(state.tokens.next, "(")) { + advance("("); + nextInnerDE(); + advance(")"); + } else { + if (isAssignment) { + var assignTarget = expression(context, 20); + if (assignTarget) { + checkLeftSideAssign(context, assignTarget); - api = { - get isJSON() { - return state.jsonMode; - }, + // if the target was a simple identifier, add it to the list to return + if (assignTarget.identifier) { + ident = assignTarget.value; + } + } + } else { + ident = identifier(context); + } + if (ident) { + identifiers.push({ id: ident, token: state.tokens.curr }); + } + } + }; - getOption: function(name) { - return state.option[name] || null; - }, + var assignmentProperty = function(context) { + var id, expr; - getCache: function(name) { - return state.cache[name]; - }, + if (checkPunctuator(state.tokens.next, "[")) { + advance("["); + expression(context, 10); + advance("]"); + advance(":"); + nextInnerDE(); + } else if (state.tokens.next.id === "(string)" || + state.tokens.next.id === "(number)") { + advance(); + advance(":"); + nextInnerDE(); + } else { + // this id will either be the property name or the property name and the assigning identifier + var isRest = spreadrest("rest"); - setCache: function(name, value) { - state.cache[name] = value; - }, + if (isRest) { + if (!state.inES9()) { + warning("W119", state.tokens.next, "object rest property", "9"); + } - warn: function(code, data) { - warningAt.apply(null, [ code, data.line, data.char ].concat(data.data)); - }, + // Due to visual symmetry with the array rest property (and the early + // design of the language feature), developers may mistakenly assume + // any expression is valid in this position. If the next token is not + // an identifier, attempt to parse an expression and issue an error. + // order to recover more gracefully from this condition. + if (state.tokens.next.type === "(identifier)") { + id = identifier(context); + } else { + expr = expression(context, 10); + error("E030", expr, expr.value); + } + } else { + id = identifier(context); + } - on: function(names, listener) { - names.split(" ").forEach(function(name) { - emitter.on(name, listener); - }.bind(this)); + if (!isRest && checkPunctuator(state.tokens.next, ":")) { + advance(":"); + nextInnerDE(); + } else if (id) { + // in this case we are assigning (not declaring), so check assignment + if (isAssignment) { + checkLeftSideAssign(context, state.tokens.curr); + } + identifiers.push({ id: id, token: state.tokens.curr }); + } + + if (isRest && checkPunctuator(state.tokens.next, ",")) { + warning("W130", state.tokens.next); + } } }; - emitter.removeAllListeners(); - (extraModules || []).forEach(function(func) { - func(api); - }); - - state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"]; + var id, value; + if (checkPunctuator(firstToken, "[")) { + if (!openingParsed) { + advance("["); + } + if (checkPunctuator(state.tokens.next, "]")) { + warning("W137", state.tokens.curr); + } + var element_after_rest = false; + while (!checkPunctuator(state.tokens.next, "]")) { + var isRest = spreadrest("rest"); - if (o && o.ignoreDelimiters) { + nextInnerDE(); - if (!Array.isArray(o.ignoreDelimiters)) { - o.ignoreDelimiters = [o.ignoreDelimiters]; + if (isRest && !element_after_rest && + checkPunctuator(state.tokens.next, ",")) { + warning("W130", state.tokens.next); + element_after_rest = true; + } + if (!isRest && checkPunctuator(state.tokens.next, "=")) { + if (checkPunctuator(state.tokens.prev, "...")) { + /* istanbul ignore next */ + advance("]"); + } else { + advance("="); + } + id = state.tokens.prev; + value = expression(context, 10); + if (value && value.identifier && value.value === "undefined") { + warning("W080", id, id.value); + } + } + if (!checkPunctuator(state.tokens.next, "]")) { + advance(","); + } } + advance("]"); + } else if (checkPunctuator(firstToken, "{")) { - o.ignoreDelimiters.forEach(function(delimiterPair) { - if (!delimiterPair.start || !delimiterPair.end) - return; - - reIgnoreStr = escapeRegex(delimiterPair.start) + - "[\\s\\S]*?" + - escapeRegex(delimiterPair.end); + if (!openingParsed) { + advance("{"); + } + if (checkPunctuator(state.tokens.next, "}")) { + warning("W137", state.tokens.curr); + } + while (!checkPunctuator(state.tokens.next, "}")) { + assignmentProperty(context); + if (checkPunctuator(state.tokens.next, "=")) { + advance("="); + id = state.tokens.prev; + value = expression(context, 10); + if (value && value.identifier && value.value === "undefined") { + warning("W080", id, id.value); + } + } + if (!checkPunctuator(state.tokens.next, "}")) { + advance(","); + if (checkPunctuator(state.tokens.next, "}")) { + // Trailing comma + // ObjectBindingPattern: { BindingPropertyList , } + break; + } + } + } + advance("}"); + } + return identifiers; + } - reIgnore = new RegExp(reIgnoreStr, "ig"); + function destructuringPatternMatch(tokens, value) { + var first = value.first; - s = s.replace(reIgnore, function(match) { - return match.replace(/./g, " "); - }); - }); - } + if (!first) + return; - lex = new Lexer(s); + _.zip(tokens, Array.isArray(first) ? first : [ first ]).forEach(function(val) { + var token = val[0]; + var value = val[1]; - lex.on("warning", function(ev) { - warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data)); + if (token && value) + token.first = value; + else if (token && token.first && !value) + /* istanbul ignore next */ + warning("W080", token.first, token.first.value); }); + } - lex.on("error", function(ev) { - errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data)); - }); - - lex.on("fatal", function(ev) { - quit("E041", ev.line, ev.from); - }); + function blockVariableStatement(type, statement, context) { + // used for both let and const statements - lex.on("Identifier", function(ev) { - emitter.emit("Identifier", ev); - }); + var noin = context & prodParams.noin; + var isLet = type === "let"; + var isConst = type === "const"; + var tokens, lone, value, letblock; - lex.on("String", function(ev) { - emitter.emit("String", ev); - }); + if (!state.inES6()) { + warning("W104", state.tokens.curr, type, "6"); + } - lex.on("Number", function(ev) { - emitter.emit("Number", ev); - }); + if (isLet && isMozillaLet()) { + advance("("); + state.funct["(scope)"].stack(); + letblock = true; + statement.declaration = false; + } - lex.start(); + statement.first = []; + for (;;) { + var names = []; + if (_.includes(["{", "["], state.tokens.next.value)) { + tokens = destructuringPattern(context); + lone = false; + } else { + tokens = [ { id: identifier(context), token: state.tokens.curr } ]; + lone = true; + } - // Check options - for (var name in o) { - if (_.has(o, name)) { - checkOption(name, state.tokens.curr); + // A `const` declaration without an initializer is permissible within the + // head of for-in and for-of statements. If this binding list is being + // parsed as part of a `for` statement of any kind, allow the initializer + // to be omitted. Although this may erroneously allow such forms from + // "C-style" `for` statements (i.e. `for (const x;;) {}`, the `for` + // statement logic includes dedicated logic to issue the error for such + // cases. + if (!noin && isConst && state.tokens.next.id !== "=") { + warning("E012", state.tokens.curr, state.tokens.curr.value); } - } - assume(); + for (var t in tokens) { + if (tokens.hasOwnProperty(t)) { + t = tokens[t]; - // combine the passed globals after we've assumed all our options - combine(predefined, g || {}); + // It is a Syntax Error if the BoundNames of BindingList contains + // "let". + if (t.id === "let") { + /* istanbul ignore next */ + warning("W024", t.token, t.id); + } - //reset values - comma.first = true; + if (state.funct["(scope)"].block.isGlobal()) { + if (predefined[t.id] === false) { + warning("W079", t.token, t.id); + } + } + if (t.id) { + state.funct["(scope)"].addbinding(t.id, { + type: type, + token: t.token }); + names.push(t.token); + } + } + } - try { - advance(); - switch (state.tokens.next.id) { - case "{": - case "[": - destructuringAssignOrJsonValue(); - break; - default: - directives(); + if (state.tokens.next.id === "=") { + statement.hasInitializer = true; - if (state.directive["use strict"]) { - if (state.option.strict !== "global") { - warning("W097", state.tokens.prev); + advance("="); + if (!noin && peek(0).id === "=" && state.tokens.next.identifier) { + warning("W120", state.tokens.next, state.tokens.next.value); + } + var id = state.tokens.prev; + value = expression(context, 10); + if (value) { + if (!isConst && value.identifier && value.value === "undefined") { + warning("W080", id, id.value); + } + if (!lone) { + destructuringPatternMatch(names, value); } } - - statements(); } - if (state.tokens.next.id !== "(end)") { - quit("E041", state.tokens.curr.line); + // Bindings are not immediately initialized in for-in and for-of + // statements. As with `const` initializers (described above), the `for` + // statement parsing logic includes + if (state.tokens.next.value !== "in" && state.tokens.next.value !== "of") { + for (t in tokens) { + if (tokens.hasOwnProperty(t)) { + t = tokens[t]; + state.funct["(scope)"].initialize(t.id); + } + } } - state.funct["(scope)"].unstack(); + statement.first = statement.first.concat(names); - } catch (err) { - if (err && err.name === "JSHintError") { - var nt = state.tokens.next || {}; - JSHINT.errors.push({ - scope : "(main)", - raw : err.raw, - code : err.code, - reason : err.message, - line : err.line || nt.line, - character : err.character || nt.from - }, null); - } else { - throw err; + if (state.tokens.next.id !== ",") { + break; } - } - // Loop over the listed "internals", and check them as well. - - if (JSHINT.scope === "(main)") { - o = o || {}; - - for (i = 0; i < JSHINT.internals.length; i += 1) { - k = JSHINT.internals[i]; - o.scope = k.elem; - itself(k.value, o, g); - } + statement.hasComma = true; + advance(","); + checkComma(); + } + if (letblock) { + advance(")"); + block(context, true, true); + statement.block = true; + state.funct["(scope)"].unstack(); } - return JSHINT.errors.length === 0; - }; - - // Modules. - itself.addModule = function(func) { - extraModules.push(func); - }; - - itself.addModule(style.register); + return statement; + } - // Data summary. - itself.data = function() { - var data = { - functions: [], - options: state.option - }; + var conststatement = stmt("const", function(context) { + return blockVariableStatement("const", this, context); + }); + conststatement.exps = true; + conststatement.declaration = true; - var fu, f, i, j, n, globals; - if (itself.errors.length) { - data.errors = itself.errors; + /** + * Determine if the current `let` token designates the beginning of a "let + * block" or "let expression" as implemented in the Mozilla SpiderMonkey + * engine. + * + * This function will only return `true` if Mozilla extensions have been + * enabled. It would be preferable to detect the language feature regardless + * of the parser's state because this would allow JSHint to instruct users to + * enable the `moz` option where necessary. This is not possible because the + * language extension is not compatible with standard JavaScript. For + * example, the following program code may describe a "let block" or a + * function invocation: + * + * let(x) + * { + * typeof x; + * } + * + * @returns {boolean} + */ + function isMozillaLet() { + return state.tokens.next.id === "(" && state.inMoz(); + } + var letstatement = stmt("let", function(context) { + return blockVariableStatement("let", this, context); + }); + letstatement.nud = function(context, rbp) { + if (isMozillaLet()) { + // create a new block scope we use only for the current expression + state.funct["(scope)"].stack(); + advance("("); + state.tokens.prev.fud(context); + advance(")"); + expression(context, rbp); + state.funct["(scope)"].unstack(); + } else { + this.exps = false; + return state.syntax["(identifier)"].nud.apply(this, arguments); } + }; + letstatement.meta = { es5: true, isFutureReservedWord: false, strictOnly: true }; + letstatement.exps = true; + letstatement.declaration = true; + letstatement.useFud = function(context) { + var next = state.tokens.next; + var nextIsBindingName; - if (state.jsonMode) { - data.json = true; + if (this.line !== next.line && !state.inES6()) { + return false; } - var impliedGlobals = state.funct["(scope)"].getImpliedGlobals(); - if (impliedGlobals.length > 0) { - data.implieds = impliedGlobals; - } + // JSHint generally interprets `let` as a reserved word even though it is + // not considered as such by the ECMAScript specification because doing so + // simplifies parsing logic. It is special-cased here so that code such as + // + // let + // let + // + // is correctly interpreted as an invalid LexicalBinding. (Without this + // consideration, the code above would be parsed as two + // IdentifierReferences.) + nextIsBindingName = next.identifier && (!isReserved(context, next) || + next.id === "let"); + + return nextIsBindingName || checkPunctuators(next, ["{", "["]) || + isMozillaLet(); + }; - if (urls.length > 0) { - data.urls = urls; - } + var varstatement = stmt("var", function(context) { + var noin = context & prodParams.noin; + var tokens, lone, value, id; - globals = state.funct["(scope)"].getUsedOrDefinedGlobals(); - if (globals.length > 0) { - data.globals = globals; - } + this.first = []; + for (;;) { + var names = []; + if (_.includes(["{", "["], state.tokens.next.value)) { + tokens = destructuringPattern(context); + lone = false; + } else { + tokens = []; + id = identifier(context); - for (i = 1; i < functions.length; i += 1) { - f = functions[i]; - fu = {}; + if (id) { + tokens.push({ id: id, token: state.tokens.curr }); + } + + lone = true; + } - for (j = 0; j < functionicity.length; j += 1) { - fu[functionicity[j]] = []; + if (state.option.varstmt) { + warning("W132", this); } - for (j = 0; j < functionicity.length; j += 1) { - if (fu[functionicity[j]].length === 0) { - delete fu[functionicity[j]]; + + for (var t in tokens) { + if (tokens.hasOwnProperty(t)) { + t = tokens[t]; + if (state.funct["(global)"] && !state.impliedClosure()) { + if (predefined[t.id] === false) { + warning("W079", t.token, t.id); + } else if (state.option.futurehostile === false) { + if ((!state.inES5() && vars.ecmaIdentifiers[5][t.id] === false) || + (!state.inES6() && vars.ecmaIdentifiers[6][t.id] === false)) { + warning("W129", t.token, t.id); + } + } + } + if (t.id) { + state.funct["(scope)"].addbinding(t.id, { + type: "var", + token: t.token }); + + names.push(t.token); + } } } - fu.name = f["(name)"]; - fu.param = f["(params)"]; - fu.line = f["(line)"]; - fu.character = f["(character)"]; - fu.last = f["(last)"]; - fu.lastcharacter = f["(lastcharacter)"]; + if (state.tokens.next.id === "=") { + this.hasInitializer = true; - fu.metrics = { - complexity: f["(metrics)"].ComplexityCount, - parameters: f["(metrics)"].arity, - statements: f["(metrics)"].statementCount - }; + state.nameStack.set(state.tokens.curr); - data.functions.push(fu); - } + advance("="); + if (peek(0).id === "=" && state.tokens.next.identifier) { + if (!noin && + !state.funct["(params)"] || + state.funct["(params)"].indexOf(state.tokens.next.value) === -1) { + warning("W120", state.tokens.next, state.tokens.next.value); + } + } + id = state.tokens.prev; + value = expression(context, 10); + if (value) { + if (!state.funct["(loopage)"] && value.identifier && + value.value === "undefined") { + warning("W080", id, id.value); + } + if (!lone) { + destructuringPatternMatch(names, value); + } + } + } - var unuseds = state.funct["(scope)"].getUnuseds(); - if (unuseds.length > 0) { - data.unused = unuseds; - } + this.first = this.first.concat(names); - for (n in member) { - if (typeof member[n] === "number") { - data.member = member; + if (state.tokens.next.id !== ",") { break; } + this.hasComma = true; + advance(","); + checkComma(); } - return data; - }; + return this; + }); + varstatement.exps = true; - itself.jshint = itself; + blockstmt("function", function(context) { + var inexport = context & prodParams.export; + var generator = false; + var isAsync = context & prodParams.preAsync; + var labelType = ""; - return itself; -}()); + if (isAsync) { + labelType = "async "; + } -// Make JSHINT a Node module, if possible. -if (typeof exports === "object" && exports) { - exports.JSHINT = JSHINT; -} + if (state.tokens.next.value === "*") { + if (isAsync && !state.inES9()) { + warning("W119", state.tokens.prev, "async generators", "9"); + } else if (!isAsync && !state.inES6(true)) { + warning("W119", state.tokens.next, "function*", "6"); + } -},{"../lodash":"/node_modules/jshint/lodash.js","./lex.js":"/node_modules/jshint/src/lex.js","./messages.js":"/node_modules/jshint/src/messages.js","./options.js":"/node_modules/jshint/src/options.js","./reg.js":"/node_modules/jshint/src/reg.js","./scope-manager.js":"/node_modules/jshint/src/scope-manager.js","./state.js":"/node_modules/jshint/src/state.js","./style.js":"/node_modules/jshint/src/style.js","./vars.js":"/node_modules/jshint/src/vars.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/lex.js":[function(_dereq_,module,exports){ -/* - * Lexical analysis and token construction. - */ + advance("*"); + labelType += "generator "; + generator = true; + } -"use strict"; + labelType += "function"; -var _ = _dereq_("../lodash"); -var events = _dereq_("events"); -var reg = _dereq_("./reg.js"); -var state = _dereq_("./state.js").state; + if (inblock) { + warning("W082", state.tokens.curr); + } + this.name = optionalidentifier(context) ? state.tokens.curr : null; -var unicodeData = _dereq_("../data/ascii-identifier-data.js"); -var asciiIdentifierStartTable = unicodeData.asciiIdentifierStartTable; -var asciiIdentifierPartTable = unicodeData.asciiIdentifierPartTable; + if (!this.name) { + if (!inexport) { + warning("W025"); + } + } else { + state.funct["(scope)"].addbinding(this.name.value, { + type: labelType, + token: state.tokens.curr, + initialized: true }); + } -// Some of these token types are from JavaScript Parser API -// while others are specific to JSHint parser. -// JS Parser API: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API + var f = doFunction(context, { + name: this.name && this.name.value, + statement: this, + type: generator ? "generator" : null, + ignoreLoopFunc: inblock // a declaration may already have warned + }); -var Token = { - Identifier: 1, - Punctuator: 2, - NumericLiteral: 3, - StringLiteral: 4, - Comment: 5, - Keyword: 6, - NullLiteral: 7, - BooleanLiteral: 8, - RegExp: 9, - TemplateHead: 10, - TemplateMiddle: 11, - TemplateTail: 12, - NoSubstTemplate: 13 -}; + // If the function declaration is strict because the surrounding code is + // strict, the invalid name will trigger E008 when the scope manager + // attempts to create a binding in the strict environment record. An error + // should only be signaled here when the function itself enables strict + // mode (the scope manager will not report an error because a declaration + // does not introduce a binding into the function's environment record). + var enablesStrictMode = f["(isStrict)"] && !state.isStrict(); + if (this.name && (f["(name)"] === "arguments" || f["(name)"] === "eval") && + enablesStrictMode) { + error("E008", this.name); + } + + // Although the parser correctly recognizes the statement boundary in this + // condition, it's support for the invalid "empty grouping" expression + // makes it tolerant of productions such as `function f() {}();`. + if (state.tokens.next.id === "(" && peek().id === ")" && peek(1).id !== "=>" && + state.tokens.next.line === state.tokens.curr.line) { + error("E039"); + } + return this; + }).declaration = true; -var Context = { - Block: 1, - Template: 2 -}; + prefix("function", function(context) { + var generator = false; + var isAsync = context & prodParams.preAsync; -// Object that handles postponed lexing verifications that checks the parsed -// environment state. + if (state.tokens.next.value === "*") { + if (isAsync && !state.inES9()) { + warning("W119", state.tokens.prev, "async generators", "9"); + } else if (!isAsync && !state.inES6(true)) { + warning("W119", state.tokens.curr, "function*", "6"); + } -function asyncTrigger() { - var _checks = []; + advance("*"); + generator = true; + } - return { - push: function(fn) { - _checks.push(fn); - }, + // This context modification restricts the use of `await` as the optional + // BindingIdentifier in async function expressions. + this.name = optionalidentifier(isAsync ? context | prodParams.async : context) ? + state.tokens.curr : null; - check: function() { - for (var check = 0; check < _checks.length; ++check) { - _checks[check](); - } + var f = doFunction(context, { + name: this.name && this.name.value, + type: generator ? "generator" : null + }); - _checks.splice(0, _checks.length); + if (generator && this.name && this.name.value === "yield") { + error("E024", this.name, "yield"); } - }; -} -/* - * Lexer for JSHint. - * - * This object does a char-by-char scan of the provided source code - * and produces a sequence of tokens. - * - * var lex = new Lexer("var i = 0;"); - * lex.start(); - * lex.token(); // returns the next token - * - * You have to use the token() method to move the lexer forward - * but you don't have to use its return value to get tokens. In addition - * to token() method returning the next token, the Lexer object also - * emits events. - * - * lex.on("Identifier", function(data) { - * if (data.name.indexOf("_") >= 0) { - * // Produce a warning. - * } - * }); - * - * Note that the token() method returns tokens in a JSLint-compatible - * format while the event emitter uses a slightly modified version of - * Mozilla's JavaScript Parser API. Eventually, we will move away from - * JSLint format. - */ -function Lexer(source) { - var lines = source; + if (this.name && (f["(name)"] === "arguments" || f["(name)"] === "eval") && + f["(isStrict)"]) { + error("E008", this.name); + } - if (typeof lines === "string") { - lines = lines - .replace(/\r\n/g, "\n") - .replace(/\r/g, "\n") - .split("\n"); - } + return this; + }); - // If the first line is a shebang (#!), make it a blank and move on. - // Shebangs are used by Node scripts. + blockstmt("if", function(context) { + var t = state.tokens.next; + increaseComplexityCount(); + advance("("); + var expr = expression(context, 0); - if (lines[0] && lines[0].substr(0, 2) === "#!") { - if (lines[0].indexOf("node") !== -1) { - state.option.node = true; + if (!expr) { + quit("E041", this); } - lines[0] = ""; - } - this.emitter = new events.EventEmitter(); - this.source = source; - this.setLines(lines); - this.prereg = true; + checkCondAssignment(expr); - this.line = 0; - this.char = 1; - this.from = 1; - this.input = ""; - this.inComment = false; - this.context = []; - this.templateStarts = []; + // When the if is within a for-in loop, check if the condition + // starts with a negation operator + var forinifcheck = null; + if (state.option.forin && state.forinifcheckneeded) { + state.forinifcheckneeded = false; // We only need to analyze the first if inside the loop + forinifcheck = state.forinifchecks[state.forinifchecks.length - 1]; + if (expr.type === "(punctuator)" && expr.value === "!") { + forinifcheck.type = "(negative)"; + } else { + forinifcheck.type = "(positive)"; + } + } - for (var i = 0; i < state.option.indent; i += 1) { - state.tab += " "; - } + advance(")", t); + var s = block(context, true, true); - // Blank out non-multi-line-commented lines when ignoring linter errors - this.ignoreLinterErrors = false; -} + // When the if is within a for-in loop and the condition has a negative form, + // check if the body contains nothing but a continue statement + if (forinifcheck && forinifcheck.type === "(negative)") { + if (s && s[0] && s[0].type === "(identifier)" && s[0].value === "continue") { + forinifcheck.type = "(negative-with-continue)"; + } + } -Lexer.prototype = { - _lines: [], + if (state.tokens.next.id === "else") { + advance("else"); + if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") { + statement(context); + } else { + block(context, true, true); + } + } + return this; + }); - inContext: function(ctxType) { - return this.context.length > 0 && this.context[this.context.length - 1].type === ctxType; - }, + blockstmt("try", function(context) { + var b; + var hasParameter = false; - pushContext: function(ctxType) { - this.context.push({ type: ctxType }); - }, + function catchParameter() { + advance("("); - popContext: function() { - return this.context.pop(); - }, + if (checkPunctuators(state.tokens.next, ["[", "{"])) { + var tokens = destructuringPattern(context); + _.each(tokens, function(token) { + if (token.id) { + state.funct["(scope)"].addParam(token.id, token.token, "exception"); + } + }); + } else if (state.tokens.next.type !== "(identifier)") { + warning("E030", state.tokens.next, state.tokens.next.value); + } else { + // only advance if an identifier is present. This allows JSHint to + // recover from the case where no value is specified. + state.funct["(scope)"].addParam(identifier(context), state.tokens.curr, "exception"); + } - isContext: function(context) { - return this.context.length > 0 && this.context[this.context.length - 1] === context; - }, + if (state.tokens.next.value === "if") { + if (!state.inMoz()) { + warning("W118", state.tokens.curr, "catch filter"); + } + advance("if"); + expression(context, 0); + } - currentContext: function() { - return this.context.length > 0 && this.context[this.context.length - 1]; - }, + advance(")"); + } - getLines: function() { - this._lines = state.lines; - return this._lines; - }, + block(context | prodParams.tryClause, true); - setLines: function(val) { - this._lines = val; - state.lines = this._lines; - }, + while (state.tokens.next.id === "catch") { + increaseComplexityCount(); + if (b && (!state.inMoz())) { + warning("W118", state.tokens.next, "multiple catch blocks"); + } + advance("catch"); + if (state.tokens.next.id !== "{") { + state.funct["(scope)"].stack("catchparams"); + hasParameter = true; + catchParameter(); + } else if (!state.inES10()) { + warning("W119", state.tokens.curr, "optional catch binding", "10"); + } + block(context, false); - /* - * Return the next i character without actually moving the - * char pointer. - */ - peek: function(i) { - return this.input.charAt(i || 0); - }, + if (hasParameter) { + state.funct["(scope)"].unstack(); + hasParameter = false; + } + b = true; + } - /* - * Move the char pointer forward i times. - */ - skip: function(i) { - i = i || 1; - this.char += i; - this.input = this.input.slice(i); - }, + if (state.tokens.next.id === "finally") { + advance("finally"); + block(context, true); + return; + } - /* - * Subscribe to a token event. The API for this method is similar - * Underscore.js i.e. you can subscribe to multiple events with - * one call: - * - * lex.on("Identifier Number", function(data) { - * // ... - * }); - */ - on: function(names, listener) { - names.split(" ").forEach(function(name) { - this.emitter.on(name, listener); - }.bind(this)); - }, + if (!b) { + error("E021", state.tokens.next, "catch", state.tokens.next.value); + } - /* - * Trigger a token event. All arguments will be passed to each - * listener. - */ - trigger: function() { - this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments)); - }, + return this; + }); - /* - * Postpone a token event. the checking condition is set as - * last parameter, and the trigger function is called in a - * stored callback. To be later called using the check() function - * by the parser. This avoids parser's peek() to give the lexer - * a false context. - */ - triggerAsync: function(type, args, checks, fn) { - checks.push(function() { - if (fn()) { - this.trigger(type, args); - } - }.bind(this)); - }, + blockstmt("while", function(context) { + var t = state.tokens.next; + state.funct["(breakage)"] += 1; + state.funct["(loopage)"] += 1; + increaseComplexityCount(); + advance("("); + checkCondAssignment(expression(context, 0)); + advance(")", t); + block(context, true, true); + state.funct["(breakage)"] -= 1; + state.funct["(loopage)"] -= 1; + return this; + }).labelled = true; - /* - * Extract a punctuator out of the next sequence of characters - * or return 'null' if its not possible. - * - * This method's implementation was heavily influenced by the - * scanPunctuator function in the Esprima parser's source code. - */ - scanPunctuator: function() { - var ch1 = this.peek(); - var ch2, ch3, ch4; + blockstmt("with", function(context) { + var t = state.tokens.next; + if (state.isStrict()) { + error("E010", state.tokens.curr); + } else if (!state.option.withstmt) { + warning("W085", state.tokens.curr); + } - switch (ch1) { - // Most common single-character punctuators - case ".": - if ((/^[0-9]$/).test(this.peek(1))) { - return null; - } - if (this.peek(1) === "." && this.peek(2) === ".") { - return { - type: Token.Punctuator, - value: "..." - }; - } - /* falls through */ - case "(": - case ")": - case ";": - case ",": - case "[": - case "]": - case ":": - case "~": - case "?": - return { - type: Token.Punctuator, - value: ch1 - }; + advance("("); + expression(context, 0); + advance(")", t); + block(context, true, true); - // A block/object opener - case "{": - this.pushContext(Context.Block); - return { - type: Token.Punctuator, - value: ch1 - }; + return this; + }); - // A block/object closer - case "}": - if (this.inContext(Context.Block)) { - this.popContext(); - } - return { - type: Token.Punctuator, - value: ch1 - }; + blockstmt("switch", function(context) { + var t = state.tokens.next; + var g = false; + var noindent = false; + var seenCase = false; - // A pound sign (for Node shebangs) - case "#": - return { - type: Token.Punctuator, - value: ch1 - }; + state.funct["(breakage)"] += 1; + advance("("); + checkCondAssignment(expression(context, 0)); + advance(")", t); + t = state.tokens.next; + advance("{"); + state.funct["(scope)"].stack(); - // We're at the end of input - case "": - return null; - } + if (state.tokens.next.from === indent) + noindent = true; - // Peek more characters + if (!noindent) + indent += state.option.indent; - ch2 = this.peek(1); - ch3 = this.peek(2); - ch4 = this.peek(3); + for (;;) { + switch (state.tokens.next.id) { + case "case": + switch (state.funct["(verb)"]) { + case "yield": + case "break": + case "case": + case "continue": + case "return": + case "switch": + case "throw": + break; + case "default": + if (state.option.leanswitch) { + warning("W145", state.tokens.next); + } - // 4-character punctuator: >>>= + break; + default: + // You can tell JSHint that you don't use break intentionally by + // adding a comment /* falls through */ on a line just before + // the next `case`. + if (!state.tokens.curr.caseFallsThrough) { + warning("W086", state.tokens.curr, "case"); + } + } - if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") { - return { - type: Token.Punctuator, - value: ">>>=" - }; - } + advance("case"); + expression(context, 0); + seenCase = true; + increaseComplexityCount(); + g = true; + advance(":"); + state.funct["(verb)"] = "case"; + break; + case "default": + switch (state.funct["(verb)"]) { + case "yield": + case "break": + case "continue": + case "return": + case "throw": + break; + case "case": + if (state.option.leanswitch) { + warning("W145", state.tokens.curr); + } - // 3-character punctuators: === !== >>> <<= >>= + break; + default: + // Do not display a warning if 'default' is the first statement or if + // there is a special /* falls through */ comment. + if (seenCase && !state.tokens.curr.caseFallsThrough) { + warning("W086", state.tokens.curr, "default"); + } + } - if (ch1 === "=" && ch2 === "=" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "===" - }; - } + advance("default"); + g = true; + advance(":"); + state.funct["(verb)"] = "default"; + break; + case "}": + if (!noindent) + indent -= state.option.indent; - if (ch1 === "!" && ch2 === "=" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "!==" - }; + advance("}", t); + state.funct["(scope)"].unstack(); + state.funct["(breakage)"] -= 1; + state.funct["(verb)"] = undefined; + return; + /* istanbul ignore next */ + case "(end)": + error("E023", state.tokens.next, "}"); + return; + default: + indent += state.option.indent; + if (g) { + switch (state.tokens.curr.id) { + /* istanbul ignore next */ + case ",": + error("E040"); + return; + case ":": + g = false; + statements(context); + break; + /* istanbul ignore next */ + default: + error("E025", state.tokens.curr); + return; + } + } else { + /* istanbul ignore else */ + if (state.tokens.curr.id === ":") { + advance(":"); + error("E024", state.tokens.curr, ":"); + statements(context); + } else { + error("E021", state.tokens.next, "case", state.tokens.next.value); + return; + } + } + indent -= state.option.indent; + } } + }).labelled = true; - if (ch1 === ">" && ch2 === ">" && ch3 === ">") { - return { - type: Token.Punctuator, - value: ">>>" - }; + stmt("debugger", function() { + if (!state.option.debug) { + warning("W087", this); } + return this; + }).exps = true; - if (ch1 === "<" && ch2 === "<" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "<<=" - }; - } + (function() { + var x = stmt("do", function(context) { + state.funct["(breakage)"] += 1; + state.funct["(loopage)"] += 1; + increaseComplexityCount(); - if (ch1 === ">" && ch2 === ">" && ch3 === "=") { - return { - type: Token.Punctuator, - value: ">>=" - }; - } + this.first = block(context, true, true); + advance("while"); + var t = state.tokens.next; + advance("("); + checkCondAssignment(expression(context, 0)); + advance(")", t); + state.funct["(breakage)"] -= 1; + state.funct["(loopage)"] -= 1; + return this; + }); + x.labelled = true; + x.exps = true; + }()); - // Fat arrow punctuator - if (ch1 === "=" && ch2 === ">") { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; + blockstmt("for", function(context) { + var s, t = state.tokens.next; + var letscope = false; + var isAsync = false; + var foreachtok = null; + + if (t.value === "each") { + foreachtok = t; + advance("each"); + if (!state.inMoz()) { + warning("W118", state.tokens.curr, "for each"); + } } - // 2-character punctuators: <= >= == != ++ -- << >> && || - // += -= *= %= &= |= ^= (but not /=, see below) - if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; - } + if (state.tokens.next.identifier && state.tokens.next.value === "await") { + advance("await"); + isAsync = true; - if ("<>=!+-*%&|^".indexOf(ch1) >= 0) { - if (ch2 === "=") { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; + if (!(context & prodParams.async)) { + error("E024", state.tokens.curr, "await"); + } else if (!state.inES9()) { + warning("W119", state.tokens.curr, "asynchronous iteration", "9"); } - - return { - type: Token.Punctuator, - value: ch1 - }; } - // Special case: /=. - - if (ch1 === "/") { - if (ch2 === "=") { - return { - type: Token.Punctuator, - value: "/=" - }; - } - - return { - type: Token.Punctuator, - value: "/" - }; - } + increaseComplexityCount(); + advance("("); - return null; - }, + // what kind of for(…) statement it is? for(…of…)? for(…in…)? for(…;…;…)? + var nextop; // contains the token of the "in" or "of" operator + var comma; // First comma punctuator at level 0 + var initializer; // First initializer at level 0 + var bindingPower; + var targets; + var target; + var decl; + var afterNext = peek(); - /* - * Extract a comment out of the next sequence of characters and/or - * lines or return 'null' if its not possible. Since comments can - * span across multiple lines this method has to move the char - * pointer. - * - * In addition to normal JavaScript comments (// and /*) this method - * also recognizes JSHint- and JSLint-specific comments such as - * /*jshint, /*jslint, /*globals and so on. - */ - scanComments: function() { - var ch1 = this.peek(); - var ch2 = this.peek(1); - var rest = this.input.substr(2); - var startLine = this.line; - var startChar = this.char; - var self = this; + var headContext = context | prodParams.noin; - // Create a comment token object and make sure it - // has all the data JSHint needs to work with special - // comments. + if (state.tokens.next.id === "var") { + advance("var"); + decl = state.tokens.curr.fud(headContext); + comma = decl.hasComma ? decl : null; + initializer = decl.hasInitializer ? decl : null; + } else if (state.tokens.next.id === "const" || + // The "let" keyword only signals a lexical binding if it is followed by + // an identifier, `{`, or `[`. Otherwise, it should be parsed as an + // IdentifierReference (i.e. in a subsquent branch). + (state.tokens.next.id === "let" && + ((afterNext.identifier && afterNext.id !== "in") || + checkPunctuators(afterNext, ["{", "["])))) { + advance(state.tokens.next.id); + // create a new block scope + letscope = true; + state.funct["(scope)"].stack(); + decl = state.tokens.curr.fud(headContext); + comma = decl.hasComma ? decl : null; + initializer = decl.hasInitializer ? decl : null; + } else if (!checkPunctuator(state.tokens.next, ";")) { + targets = []; + + while (state.tokens.next.value !== "in" && + state.tokens.next.value !== "of" && + !checkPunctuator(state.tokens.next, ";")) { + + if (checkPunctuators(state.tokens.next, ["{", "["])) { + destructuringPattern(headContext, { assignment: true }) + .forEach(function(elem) { + this.push(elem.token); + }, targets); + if (checkPunctuator(state.tokens.next, "=")) { + advance("="); + initializer = state.tokens.curr; + expression(headContext, 10); + } + } else { + target = expression(headContext, 10); + + if (target) { + if (target.type === "(identifier)") { + targets.push(target); + } else if (checkPunctuator(target, "=")) { + initializer = target; + targets.push(target); + } + } + } - function commentToken(label, body, opt) { - var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"]; - var isSpecial = false; - var value = label + body; - var commentType = "plain"; - opt = opt || {}; + if (checkPunctuator(state.tokens.next, ",")) { + advance(","); - if (opt.isMultiline) { - value += "*/"; + if (!comma) { + comma = state.tokens.curr; + } + } } - body = body.replace(/\n/g, " "); + //checkLeftSideAssign(target, nextop); - if (label === "/*" && reg.fallsThrough.test(body)) { - isSpecial = true; - commentType = "falls through"; + // In the event of a syntax error, do not issue warnings regarding the + // implicit creation of bindings. + if (!initializer && !comma) { + targets.forEach(function(token) { + if (!state.funct["(scope)"].has(token.value)) { + warning("W088", token, token.value); + } + }); } + } - special.forEach(function(str) { - if (isSpecial) { - return; - } + nextop = state.tokens.next; - // Don't recognize any special comments other than jshint for single-line - // comments. This introduced many problems with legit comments. - if (label === "//" && str !== "jshint") { - return; - } + if (isAsync && nextop.value !== "of") { + error("E066", nextop); + } - if (body.charAt(str.length) === " " && body.substr(0, str.length) === str) { - isSpecial = true; - label = label + str; - body = body.substr(str.length); - } + // if we're in a for (… in|of …) statement + if (_.includes(["in", "of"], nextop.value)) { + if (nextop.value === "of") { + bindingPower = 20; - if (!isSpecial && body.charAt(0) === " " && body.charAt(str.length + 1) === " " && - body.substr(1, str.length) === str) { - isSpecial = true; - label = label + " " + str; - body = body.substr(str.length + 1); + if (!state.inES6()) { + warning("W104", nextop, "for of", "6"); } + } else { + bindingPower = 0; + } + if (comma) { + error("W133", comma, nextop.value, "more than one ForBinding"); + } + if (initializer) { + error("W133", initializer, nextop.value, "initializer is forbidden"); + } + if (target && !comma && !initializer) { + checkLeftSideAssign(context, target, nextop); + } - if (!isSpecial) { - return; - } + advance(nextop.value); - switch (str) { - case "member": - commentType = "members"; - break; - case "global": - commentType = "globals"; - break; - default: - var options = body.split(":").map(function(v) { - return v.replace(/^\s+/, "").replace(/\s+$/, ""); - }); + // The binding power is variable because for-in statements accept any + // Expression in this position, while for-of statements are limited to + // AssignmentExpressions. For example: + // + // for ( LeftHandSideExpression in Expression ) Statement + // for ( LeftHandSideExpression of AssignmentExpression ) Statement + expression(context, bindingPower); + advance(")", t); - if (options.length === 2) { - switch (options[0]) { - case "ignore": - switch (options[1]) { - case "start": - self.ignoringLinterErrors = true; - isSpecial = false; - break; - case "end": - self.ignoringLinterErrors = false; - isSpecial = false; - break; - } - } - } + if (nextop.value === "in" && state.option.forin) { + state.forinifcheckneeded = true; - commentType = str; + if (state.forinifchecks === undefined) { + state.forinifchecks = []; } - }); - return { - type: Token.Comment, - commentType: commentType, - value: value, - body: body, - isSpecial: isSpecial, - isMultiline: opt.isMultiline || false, - isMalformed: opt.isMalformed || false - }; - } + // Push a new for-in-if check onto the stack. The type will be modified + // when the loop's body is parsed and a suitable if statement exists. + state.forinifchecks.push({ + type: "(none)" + }); + } - // End of unbegun comment. Raise an error and skip that input. - if (ch1 === "*" && ch2 === "/") { - this.trigger("error", { - code: "E018", - line: startLine, - character: startChar - }); + state.funct["(breakage)"] += 1; + state.funct["(loopage)"] += 1; - this.skip(2); - return null; - } + s = block(context, true, true); - // Comments must start either with // or /* - if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) { - return null; - } + if (nextop.value === "in" && state.option.forin) { + if (state.forinifchecks && state.forinifchecks.length > 0) { + var check = state.forinifchecks.pop(); - // One-line comment - if (ch2 === "/") { - this.skip(this.input.length); // Skip to the EOL. - return commentToken("//", rest); - } + if (// No if statement or not the first statement in loop body + s && s.length > 0 && (typeof s[0] !== "object" || s[0].value !== "if") || + // Positive if statement is not the only one in loop body + check.type === "(positive)" && s.length > 1 || + // Negative if statement but no continue + check.type === "(negative)") { + warning("W089", this); + } + } - var body = ""; + // Reset the flag in case no if statement was contained in the loop body + state.forinifcheckneeded = false; + } - /* Multi-line comment */ - if (ch2 === "*") { - this.inComment = true; - this.skip(2); + state.funct["(breakage)"] -= 1; + state.funct["(loopage)"] -= 1; - while (this.peek() !== "*" || this.peek(1) !== "/") { - if (this.peek() === "") { // End of Line - body += "\n"; + } else { + if (foreachtok) { + error("E045", foreachtok); + } - // If we hit EOF and our comment is still unclosed, - // trigger an error and end the comment implicitly. - if (!this.nextLine()) { - this.trigger("error", { - code: "E017", - line: startLine, - character: startChar - }); + advance(";"); + if (decl && decl.first && decl.first[0]) { + if (decl.value === "const" && !decl.hasInitializer) { + warning("E012", decl, decl.first[0].value); + } - this.inComment = false; - return commentToken("/*", body, { - isMultiline: true, - isMalformed: true - }); + decl.first.forEach(function(token) { + state.funct["(scope)"].initialize(token.value); + }); + } + + // start loopage after the first ; as the next two expressions are executed + // on every loop + state.funct["(loopage)"] += 1; + if (state.tokens.next.id !== ";") { + checkCondAssignment(expression(context, 0)); + } + + advance(";"); + if (state.tokens.next.id === ";") { + error("E021", state.tokens.next, ")", ";"); + } + if (state.tokens.next.id !== ")") { + for (;;) { + expression(context, 0); + if (state.tokens.next.id !== ",") { + break; } - } else { - body += this.peek(); - this.skip(); + advance(","); + checkComma(); } } - - this.skip(2); - this.inComment = false; - return commentToken("/*", body, { isMultiline: true }); + advance(")", t); + state.funct["(breakage)"] += 1; + block(context, true, true); + state.funct["(breakage)"] -= 1; + state.funct["(loopage)"] -= 1; } - }, - /* - * Extract a keyword out of the next sequence of characters or - * return 'null' if its not possible. - */ - scanKeyword: function() { - var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input); - var keywords = [ - "if", "in", "do", "var", "for", "new", - "try", "let", "this", "else", "case", - "void", "with", "enum", "while", "break", - "catch", "throw", "const", "yield", "class", - "super", "return", "typeof", "delete", - "switch", "export", "import", "default", - "finally", "extends", "function", "continue", - "debugger", "instanceof" - ]; - - if (result && keywords.indexOf(result[0]) >= 0) { - return { - type: Token.Keyword, - value: result[0] - }; + // unstack loop blockscope + if (letscope) { + state.funct["(scope)"].unstack(); } + return this; + }).labelled = true; - return null; - }, - /* - * Extract a JavaScript identifier out of the next sequence of - * characters or return 'null' if its not possible. In addition, - * to Identifier this method can also produce BooleanLiteral - * (true/false) and NullLiteral (null). - */ - scanIdentifier: function() { - var id = ""; - var index = 0; - var type, char; + stmt("break", function() { + var v = state.tokens.next.value; - function isNonAsciiIdentifierStart(code) { - return code > 256; + if (state.tokens.next.identifier && + sameLine(state.tokens.curr, state.tokens.next)) { + if (!state.funct["(scope)"].funct.hasLabel(v)) { + warning("W090", state.tokens.next, v); + } + this.first = state.tokens.next; + advance(); + } else { + if (state.funct["(breakage)"] === 0) + warning("W052", state.tokens.next, this.value); } - function isNonAsciiIdentifierPart(code) { - return code > 256; + reachable(this); + + return this; + }).exps = true; + + + stmt("continue", function() { + var v = state.tokens.next.value; + + if (state.funct["(breakage)"] === 0 || !state.funct["(loopage)"]) { + warning("W052", state.tokens.next, this.value); } - function isHexDigit(str) { - return (/^[0-9a-fA-F]$/).test(str); + if (state.tokens.next.identifier) { + if (sameLine(state.tokens.curr, state.tokens.next)) { + if (!state.funct["(scope)"].funct.hasLabel(v)) { + warning("W090", state.tokens.next, v); + } + this.first = state.tokens.next; + advance(); + } } - var readUnicodeEscapeSequence = function() { - /*jshint validthis:true */ - index += 1; + reachable(this); - if (this.peek(index) !== "u") { - return null; - } + return this; + }).exps = true; - var ch1 = this.peek(index + 1); - var ch2 = this.peek(index + 2); - var ch3 = this.peek(index + 3); - var ch4 = this.peek(index + 4); - var code; - if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) { - code = parseInt(ch1 + ch2 + ch3 + ch4, 16); + stmt("return", function(context) { + if (sameLine(this, state.tokens.next)) { + if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { + this.first = expression(context, 0); - if (asciiIdentifierPartTable[code] || isNonAsciiIdentifierPart(code)) { - index += 5; - return "\\u" + ch1 + ch2 + ch3 + ch4; + if (this.first && + this.first.type === "(punctuator)" && this.first.value === "=" && + !this.first.paren && !state.option.boss) { + warning("W093", this.first); } - return null; + if (state.option.noreturnawait && context & prodParams.async && + !(context & prodParams.tryClause) && + this.first.identifier && this.first.value === "await") { + warning("W146", this.first); + } + } + } else { + if (state.tokens.next.type === "(punctuator)" && + ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) { + nolinebreak(this); // always warn (Line breaking error) } + } - return null; - }.bind(this); + reachable(this); - var getIdentifierStart = function() { - /*jshint validthis:true */ - var chr = this.peek(index); - var code = chr.charCodeAt(0); + return this; + }).exps = true; - if (code === 92) { - return readUnicodeEscapeSequence(); + prefix("await", function(context) { + if (context & prodParams.async) { + // If the parameters of the current function scope have not been defined, + // it is because the current expression is contained within the parameter + // list. + if (!state.funct["(params)"]) { + error("E024", this, "await"); } - if (code < 128) { - if (asciiIdentifierStartTable[code]) { - index += 1; - return chr; - } + expression(context, 10); + return this; + } else { + this.exps = false; + return state.syntax["(identifier)"].nud.apply(this, arguments); + } + }).exps = true; - return null; - } + (function(asyncSymbol) { + asyncSymbol.meta = { es5: true, isFutureReservedWord: true, strictOnly: true }; + asyncSymbol.isFunc = function() { + var next = state.tokens.next; + var afterParens; - if (isNonAsciiIdentifierStart(code)) { - index += 1; - return chr; + if (this.line !== next.line) { + return false; } - return null; - }.bind(this); + if (next.id === "function") { + return true; + } - var getIdentifierPart = function() { - /*jshint validthis:true */ - var chr = this.peek(index); - var code = chr.charCodeAt(0); + if (next.id === "(") { + afterParens = peekThroughParens(0); - if (code === 92) { - return readUnicodeEscapeSequence(); + return afterParens.id === "=>"; } - if (code < 128) { - if (asciiIdentifierPartTable[code]) { - index += 1; - return chr; - } - - return null; + if (next.identifier) { + return peek().id === "=>"; } - if (isNonAsciiIdentifierPart(code)) { - index += 1; - return chr; + return false; + }; + asyncSymbol.useFud = asyncSymbol.isFunc; + // async function declaration + asyncSymbol.fud = function(context) { + if (!state.inES8()) { + warning("W119", this, "async functions", "8"); + } + context |= prodParams.preAsync; + context |= prodParams.initial; + this.func = expression(context, 0); + this.block = this.func.block; + this.exps = this.func.exps; + return this; + }; + asyncSymbol.exps = true; + delete asyncSymbol.reserved; + }(prefix("async", function(context, rbp) { + if (this.isFunc(context)) { + if (!state.inES8()) { + warning("W119", this, "async functions", "8"); } - return null; - }.bind(this); + context |= prodParams.preAsync; + this.func = expression(context, rbp); + this.identifier = false; + return this; + } - function removeEscapeSequences(id) { - return id.replace(/\\u([0-9a-fA-F]{4})/g, function(m0, codepoint) { - return String.fromCharCode(parseInt(codepoint, 16)); - }); + this.exps = false; + return state.syntax["(identifier)"].nud.apply(this, arguments); + }))); + + (function(yieldSymbol) { + yieldSymbol.rbp = yieldSymbol.lbp = 25; + yieldSymbol.exps = true; + })(prefix("yield", function(context) { + if (state.inMoz()) { + return mozYield.call(this, context); } - char = getIdentifierStart(); - if (char === null) { - return null; + if (!(context & prodParams.yield)) { + this.exps = false; + return state.syntax["(identifier)"].nud.apply(this, arguments); } - id = char; - for (;;) { - char = getIdentifierPart(); + var prev = state.tokens.prev; - if (char === null) { - break; - } + // If the parameters of the current function scope have not been defined, + // it is because the current expression is contained within the parameter + // list. + if (!state.funct["(params)"]) { + error("E024", this, "yield"); + } - id += char; + if (!this.beginsStmt && prev.lbp > 30 && !checkPunctuators(prev, ["("])) { + error("E061", this); } - switch (id) { - case "true": - case "false": - type = Token.BooleanLiteral; - break; - case "null": - type = Token.NullLiteral; - break; - default: - type = Token.Identifier; + if (!state.inES6()) { + warning("W104", state.tokens.curr, "yield", "6"); } + state.funct["(yielded)"] = true; - return { - type: type, - value: removeEscapeSequences(id), - text: id, - tokenLength: id.length - }; - }, + if (state.tokens.next.value === "*") { + advance("*"); + } - /* - * Extract a numeric literal out of the next sequence of - * characters or return 'null' if its not possible. This method - * supports all numeric literals described in section 7.8.3 - * of the EcmaScript 5 specification. - * - * This method's implementation was heavily influenced by the - * scanNumericLiteral function in the Esprima parser's source code. - */ - scanNumericLiteral: function() { - var index = 0; - var value = ""; - var length = this.input.length; - var char = this.peek(index); - var bad; - var isAllowedDigit = isDecimalDigit; - var base = 10; - var isLegacy = false; + // Parse operand + if (state.tokens.curr.value === "*" || sameLine(state.tokens.curr, state.tokens.next)) { + if (state.tokens.next.nud) { - function isDecimalDigit(str) { - return (/^[0-9]$/).test(str); - } + nobreaknonadjacent(state.tokens.curr, state.tokens.next); + this.first = expression(context, 10); - function isOctalDigit(str) { - return (/^[0-7]$/).test(str); + if (this.first.type === "(punctuator)" && this.first.value === "=" && + !this.first.paren && !state.option.boss) { + warning("W093", this.first); + } + } else if (state.tokens.next.led) { + if (state.tokens.next.id !== ",") { + error("W017", state.tokens.next); + } + } } - function isBinaryDigit(str) { - return (/^[01]$/).test(str); - } + return this; + })); - function isHexDigit(str) { - return (/^[0-9a-fA-F]$/).test(str); + /** + * Parsing logic for non-standard Mozilla implementation of `yield` + * expressions. + */ + var mozYield = function(context) { + var prev = state.tokens.prev; + if (state.inES6(true) && !(context & prodParams.yield)) { + error("E046", state.tokens.curr, "yield"); } + state.funct["(yielded)"] = true; + var delegatingYield = false; - function isIdentifierStart(ch) { - return (ch === "$") || (ch === "_") || (ch === "\\") || - (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z"); + if (state.tokens.next.value === "*") { + delegatingYield = true; + advance("*"); } - // Numbers must start either with a decimal digit or a point. + if (sameLine(this, state.tokens.next)) { + if (delegatingYield || + (state.tokens.next.id !== ";" && !state.option.asi && + !state.tokens.next.reach && state.tokens.next.nud)) { - if (char !== "." && !isDecimalDigit(char)) { - return null; + nobreaknonadjacent(state.tokens.curr, state.tokens.next); + this.first = expression(context, 10); + + if (this.first.type === "(punctuator)" && this.first.value === "=" && + !this.first.paren && !state.option.boss) { + warning("W093", this.first); + } + } + if (state.tokens.next.id !== ")" && + (prev.lbp > 30 || (!prev.assign && !isEndOfExpr()))) { + error("E050", this); + } + } else if (!state.option.asi) { + nolinebreak(this); // always warn (Line breaking error) } + return this; + }; - if (char !== ".") { - value = this.peek(index); - index += 1; - char = this.peek(index); + stmt("throw", function(context) { + nolinebreak(this); + this.first = expression(context, 20); - if (value === "0") { - // Base-16 numbers. - if (char === "x" || char === "X") { - isAllowedDigit = isHexDigit; - base = 16; + reachable(this); - index += 1; - value += char; - } + return this; + }).exps = true; - // Base-8 numbers. - if (char === "o" || char === "O") { - isAllowedDigit = isOctalDigit; - base = 8; + prefix("import", function(context) { + var mp = metaProperty(context, "meta", function() { + if (!state.inES11(true)) { + warning("W119", state.tokens.prev, "import.meta", "11"); + } + if (!state.option.module) { + error("E070", state.tokens.prev); + } + }); - if (!state.inES6(true)) { - this.trigger("warning", { - code: "W119", - line: this.line, - character: this.char, - data: [ "Octal integer literal", "6" ] - }); - } + if (mp) { + return mp; + } - index += 1; - value += char; - } + if (!checkPunctuator(state.tokens.next, "(")) { + return state.syntax["(identifier)"].nud.call(this, context); + } - // Base-2 numbers. - if (char === "b" || char === "B") { - isAllowedDigit = isBinaryDigit; - base = 2; + if (!state.inES11()) { + warning("W119", state.tokens.curr, "dynamic import", "11"); + } - if (!state.inES6(true)) { - this.trigger("warning", { - code: "W119", - line: this.line, - character: this.char, - data: [ "Binary integer literal", "6" ] - }); - } + advance("("); + expression(context, 10); + advance(")"); + return this; + }); - index += 1; - value += char; - } + var importSymbol = stmt("import", function(context) { + if (!state.funct["(scope)"].block.isGlobal()) { + error("E053", state.tokens.curr, "Import"); + } - // Legacy base-8 numbers. - if (isOctalDigit(char)) { - isAllowedDigit = isOctalDigit; - base = 8; - isLegacy = true; - bad = false; + if (!state.inES6()) { + warning("W119", state.tokens.curr, "import", "6"); + } - index += 1; - value += char; - } + if (state.tokens.next.type === "(string)") { + // ModuleSpecifier :: StringLiteral + advance("(string)"); + return this; + } - // Decimal numbers that start with '0' such as '09' are illegal - // but we still parse them and return as malformed. + if (state.tokens.next.identifier) { + // ImportClause :: ImportedDefaultBinding + this.name = identifier(context); + // Import bindings are immutable (see ES6 8.1.1.5.5) + state.funct["(scope)"].addbinding(this.name, { + type: "import", + initialized: true, + token: state.tokens.curr }); - if (!isOctalDigit(char) && isDecimalDigit(char)) { - index += 1; - value += char; - } + if (state.tokens.next.value === ",") { + // ImportClause :: ImportedDefaultBinding , NameSpaceImport + // ImportClause :: ImportedDefaultBinding , NamedImports + advance(","); + // At this point, we intentionally fall through to continue matching + // either NameSpaceImport or NamedImports. + // Discussion: + // https://github.com/jshint/jshint/pull/2144#discussion_r23978406 + } else { + advance("from"); + advance("(string)"); + return this; } + } - while (index < length) { - char = this.peek(index); + if (state.tokens.next.id === "*") { + // ImportClause :: NameSpaceImport + advance("*"); + advance("as"); + if (state.tokens.next.identifier) { + this.name = identifier(context); + // Import bindings are immutable (see ES6 8.1.1.5.5) + state.funct["(scope)"].addbinding(this.name, { + type: "import", + initialized: true, + token: state.tokens.curr }); + } + } else { + // ImportClause :: NamedImports + advance("{"); + for (;;) { + if (state.tokens.next.value === "}") { + advance("}"); + break; + } + var importName; + if (peek().value === "as") { + identifier(context, true); + advance("as"); + importName = identifier(context); + } else { + importName = identifier(context); + } + + // Import bindings are immutable (see ES6 8.1.1.5.5) + state.funct["(scope)"].addbinding(importName, { + type: "import", + initialized: true, + token: state.tokens.curr }); - if (isLegacy && isDecimalDigit(char)) { - // Numbers like '019' (note the 9) are not valid octals - // but we still parse them and mark as malformed. - bad = true; - } else if (!isAllowedDigit(char)) { + if (state.tokens.next.value === ",") { + advance(","); + } else if (state.tokens.next.value === "}") { + advance("}"); + break; + } else { + error("E024", state.tokens.next, state.tokens.next.value); break; } - value += char; - index += 1; } + } - if (isAllowedDigit !== isDecimalDigit) { - if (!isLegacy && value.length <= 2) { // 0x - return { - type: Token.NumericLiteral, - value: value, - isMalformed: true - }; - } + // FromClause + advance("from"); + advance("(string)"); - if (index < length) { - char = this.peek(index); - if (isIdentifierStart(char)) { - return null; - } - } + // Support for ES2015 modules was released without warning for `import` + // declarations that lack bindings. Issuing a warning would therefor + // constitute a breaking change. + // TODO: enable this warning in JSHint 3 + // if (hasBindings) { + // warning("W142", this, "import", moduleSpecifier); + // } - return { - type: Token.NumericLiteral, - value: value, - base: base, - isLegacy: isLegacy, - isMalformed: false - }; - } + return this; + }); + importSymbol.exps = true; + importSymbol.reserved = true; + importSymbol.meta = { isFutureReservedWord: true, es5: true }; + importSymbol.useFud = function() { + return !(checkPunctuators(state.tokens.next, [".", "("])); + }; + importSymbol.rbp = 161; + + stmt("export", function(context) { + var ok = true; + var token; + var moduleSpecifier; + context = context | prodParams.export; + + if (!state.inES6()) { + warning("W119", state.tokens.curr, "export", "6"); + ok = false; } - // Decimal digits. + if (!state.funct["(scope)"].block.isGlobal()) { + error("E053", state.tokens.curr, "Export"); + ok = false; + } - if (char === ".") { - value += char; - index += 1; + if (state.tokens.next.value === "*") { + // ExportDeclaration :: export * FromClause + // ExportDeclaration :: export * as IdentifierName FromClause + advance("*"); - while (index < length) { - char = this.peek(index); - if (!isDecimalDigit(char)) { - break; + if (state.tokens.next.value === "as") { + if (!state.inES11()) { + warning("W119", state.tokens.curr, "export * as ns from", "11"); } - value += char; - index += 1; + advance("as"); + identifier(context, true); + state.funct["(scope)"].setExported(null, state.tokens.curr); } + + advance("from"); + advance("(string)"); + return this; } - // Exponent part. + if (state.tokens.next.type === "default") { + // ExportDeclaration :: + // export default [lookahead ∉ { function, class }] AssignmentExpression[In] ; + // export default HoistableDeclaration + // export default ClassDeclaration - if (char === "e" || char === "E") { - value += char; - index += 1; - char = this.peek(index); + // because the 'name' of a default-exported function is, confusingly, 'default' + // see https://bocoup.com/blog/whats-in-a-function-name + state.nameStack.set(state.tokens.next); - if (char === "+" || char === "-") { - value += this.peek(index); - index += 1; + advance("default"); + var def = state.tokens.curr; + var exportType = state.tokens.next.id; + if (exportType === "function") { + this.block = true; + advance("function"); + token = state.syntax["function"].fud(context); + state.funct["(scope)"].setExported(token.name, def); + } else if (exportType === "async" && peek().id === "function") { + this.block = true; + advance("async"); + advance("function"); + token = state.syntax["function"].fud(context | prodParams.preAsync); + state.funct["(scope)"].setExported(token.name, def); + } else if (exportType === "class") { + this.block = true; + advance("class"); + token = state.syntax["class"].fud(context); + state.funct["(scope)"].setExported(token.name, def); + } else { + expression(context, 10); + state.funct["(scope)"].setExported(null, def); } + return this; + } + if (state.tokens.next.value === "{") { + // ExportDeclaration :: export ExportClause + advance("{"); + var exportedTokens = []; + while (!checkPunctuator(state.tokens.next, "}")) { + if (!state.tokens.next.identifier) { + /* istanbul ignore next */ + error("E030", state.tokens.next, state.tokens.next.value); + } + advance(); - char = this.peek(index); - if (isDecimalDigit(char)) { - value += char; - index += 1; - - while (index < length) { - char = this.peek(index); - if (!isDecimalDigit(char)) { - break; + if (state.tokens.next.value === "as") { + advance("as"); + if (!state.tokens.next.identifier) { + /* istanbul ignore next */ + error("E030", state.tokens.next, state.tokens.next.value); } - value += char; - index += 1; + exportedTokens.push({ + local: state.tokens.prev, + export: state.tokens.next + }); + advance(); + } else { + exportedTokens.push({ + local: state.tokens.curr, + export: state.tokens.curr + }); + } + + if (!checkPunctuator(state.tokens.next, "}")) { + advance(","); } - } else { - return null; } - } + advance("}"); + if (state.tokens.next.value === "from") { + // ExportDeclaration :: export ExportClause FromClause + advance("from"); + moduleSpecifier = state.tokens.next; + advance("(string)"); + } else if (ok) { + exportedTokens.forEach(function(x) { + state.funct["(scope)"].setExported(x.local, x.export); + }); + } - if (index < length) { - char = this.peek(index); - if (isIdentifierStart(char)) { - return null; + if (exportedTokens.length === 0) { + if (moduleSpecifier) { + warning("W142", this, "export", moduleSpecifier.value); + } else { + warning("W141", this, "export"); + } } + + return this; + } else if (state.tokens.next.id === "var") { + // ExportDeclaration :: export VariableStatement + advance("var"); + token = state.tokens.curr.fud(context); + token.first.forEach(function(binding) { + state.funct["(scope)"].setExported(binding, binding); + }); + } else if (state.tokens.next.id === "let") { + // ExportDeclaration :: export VariableStatement + advance("let"); + token = state.tokens.curr.fud(context); + token.first.forEach(function(binding) { + state.funct["(scope)"].setExported(binding, binding); + }); + } else if (state.tokens.next.id === "const") { + // ExportDeclaration :: export VariableStatement + advance("const"); + token = state.tokens.curr.fud(context); + token.first.forEach(function(binding) { + state.funct["(scope)"].setExported(binding, binding); + }); + } else if (state.tokens.next.id === "function") { + // ExportDeclaration :: export Declaration + this.block = true; + advance("function"); + token = state.syntax["function"].fud(context); + state.funct["(scope)"].setExported(token.name, token.name); + } else if (state.tokens.next.id === "async" && peek().id === "function") { + // ExportDeclaration :: export Declaration + this.block = true; + advance("async"); + advance("function"); + token = state.syntax["function"].fud(context | prodParams.preAsync); + state.funct["(scope)"].setExported(token.name, token.name); + } else if (state.tokens.next.id === "class") { + // ExportDeclaration :: export Declaration + this.block = true; + advance("class"); + token = state.syntax["class"].fud(context); + state.funct["(scope)"].setExported(token.name, token.name); + } else { + /* istanbul ignore next */ + error("E024", state.tokens.next, state.tokens.next.value); } - return { - type: Token.NumericLiteral, - value: value, - base: base, - isMalformed: !isFinite(value) - }; - }, + return this; + }).exps = true; + /** + * Determine if SuperCall or SuperProperty may be used in the current context + * (as described by the provided "functor" object). + * + * @param {string} type - one of "property" or "call" + * @param {object} funct - a "functor" object describing the current function + * context + * + * @returns {boolean} + */ + function supportsSuper(type, funct) { + if (type === "call" && funct["(async)"]) { + return false; + } - // Assumes previously parsed character was \ (=== '\\') and was not skipped. - scanEscapeSequence: function(checks) { - var allowNewLine = false; - var jump = 1; - this.skip(); - var char = this.peek(); + if (type === "property" && funct["(method)"]) { + return true; + } - switch (char) { - case "'": - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\'" ] - }, checks, function() {return state.jsonMode; }); - break; - case "b": - char = "\\b"; - break; - case "f": - char = "\\f"; - break; - case "n": - char = "\\n"; - break; - case "r": - char = "\\r"; - break; - case "t": - char = "\\t"; - break; - case "0": - char = "\\0"; + if (type === "call" && funct["(statement)"] && + funct["(statement)"].id === "class") { + return true; + } - // Octal literals fail in strict mode. - // Check if the number is between 00 and 07. - var n = parseInt(this.peek(1), 10); - this.triggerAsync("warning", { - code: "W115", - line: this.line, - character: this.char - }, checks, - function() { return n >= 0 && n <= 7 && state.isStrict(); }); - break; - case "u": - var hexCode = this.input.substr(1, 4); - var code = parseInt(hexCode, 16); - if (isNaN(code)) { - this.trigger("warning", { - code: "W052", - line: this.line, - character: this.char, - data: [ "u" + hexCode ] - }); - } - char = String.fromCharCode(code); - jump = 5; - break; - case "v": - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\v" ] - }, checks, function() { return state.jsonMode; }); + if (funct["(arrow)"]) { + return supportsSuper(type, funct["(context)"]); + } - char = "\v"; - break; - case "x": - var x = parseInt(this.input.substr(1, 2), 16); + return false; + } - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\x-" ] - }, checks, function() { return state.jsonMode; }); + var superNud = function() { + var next = state.tokens.next; - char = String.fromCharCode(x); - jump = 3; - break; - case "\\": - char = "\\\\"; - break; - case "\"": - char = "\\\""; - break; - case "/": - break; - case "": - allowNewLine = true; - char = ""; - break; + if (checkPunctuators(next, ["[", "."])) { + if (!supportsSuper("property", state.funct)) { + error("E063", this); + } + } else if (checkPunctuator(next, "(")) { + if (!supportsSuper("call", state.funct)) { + error("E064", this); + } + } else { + error("E024", next, next.value || next.id); } - return { char: char, jump: jump, allowNewLine: allowNewLine }; - }, + return this; + }; - /* - * Extract a template literal out of the next sequence of characters - * and/or lines or return 'null' if its not possible. Since template - * literals can span across multiple lines, this method has to move - * the char pointer. - */ - scanTemplateLiteral: function(checks) { - var tokenType; - var value = ""; - var ch; - var startLine = this.line; - var startChar = this.char; - var depth = this.templateStarts.length; + // Future Reserved Words - if (!state.inES6(true)) { - // Only lex template strings in ESNext mode. - return null; - } else if (this.peek() === "`") { - // Template must start with a backtick. - tokenType = Token.TemplateHead; - this.templateStarts.push({ line: this.line, char: this.char }); - depth = this.templateStarts.length; - this.skip(1); - this.pushContext(Context.Template); - } else if (this.inContext(Context.Template) && this.peek() === "}") { - // If we're in a template context, and we have a '}', lex a TemplateMiddle. - tokenType = Token.TemplateMiddle; - } else { - // Go lex something else. - return null; - } + FutureReservedWord("abstract"); + FutureReservedWord("boolean"); + FutureReservedWord("byte"); + FutureReservedWord("char"); + FutureReservedWord("double"); + FutureReservedWord("enum", { es5: true }); + FutureReservedWord("export", { es5: true }); + FutureReservedWord("extends", { es5: true }); + FutureReservedWord("final"); + FutureReservedWord("float"); + FutureReservedWord("goto"); + FutureReservedWord("implements", { es5: true, strictOnly: true }); + FutureReservedWord("int"); + FutureReservedWord("interface", { es5: true, strictOnly: true }); + FutureReservedWord("long"); + FutureReservedWord("native"); + FutureReservedWord("package", { es5: true, strictOnly: true }); + FutureReservedWord("private", { es5: true, strictOnly: true }); + FutureReservedWord("protected", { es5: true, strictOnly: true }); + FutureReservedWord("public", { es5: true, strictOnly: true }); + FutureReservedWord("short"); + FutureReservedWord("static", { es5: true, strictOnly: true }); + FutureReservedWord("synchronized"); + FutureReservedWord("transient"); + FutureReservedWord("volatile"); - while (this.peek() !== "`") { - while ((ch = this.peek()) === "") { - value += "\n"; - if (!this.nextLine()) { - // Unclosed template literal --- point to the starting "`" - var startPos = this.templateStarts.pop(); - this.trigger("error", { - code: "E052", - line: startPos.line, - character: startPos.char - }); - return { - type: tokenType, - value: value, - startLine: startLine, - startChar: startChar, - isUnclosed: true, - depth: depth, - context: this.popContext() - }; + // this function is used to determine whether a squarebracket or a curlybracket + // expression is a comprehension array, destructuring assignment or a json value. + + var lookupBlockType = function() { + var pn, pn1, prev; + var i = -1; + var bracketStack = 0; + var ret = {}; + if (checkPunctuators(state.tokens.curr, ["[", "{"])) { + bracketStack += 1; + } + do { + prev = i === -1 ? state.tokens.curr : pn; + pn = i === -1 ? state.tokens.next : peek(i); + pn1 = peek(i + 1); + i = i + 1; + if (checkPunctuators(pn, ["[", "{"])) { + bracketStack += 1; + } else if (checkPunctuators(pn, ["]", "}"])) { + bracketStack -= 1; + } + if (bracketStack === 1 && pn.identifier && pn.value === "for" && + !checkPunctuator(prev, ".")) { + ret.isCompArray = true; + ret.notJson = true; + break; + } + if (bracketStack === 0 && checkPunctuators(pn, ["}", "]"])) { + if (pn1.value === "=") { + ret.isDestAssign = true; + ret.notJson = true; + break; + } else if (pn1.value === ".") { + ret.notJson = true; + break; } } - - if (ch === '$' && this.peek(1) === '{') { - value += '${'; - this.skip(2); - return { - type: tokenType, - value: value, - startLine: startLine, - startChar: startChar, - isUnclosed: false, - depth: depth, - context: this.currentContext() - }; - } else if (ch === '\\') { - var escape = this.scanEscapeSequence(checks); - value += escape.char; - this.skip(escape.jump); - } else if (ch !== '`') { - // Otherwise, append the value and continue. - value += ch; - this.skip(1); + if (checkPunctuator(pn, ";")) { + ret.notJson = true; } + } while (bracketStack > 0 && pn.id !== "(end)"); + return ret; + }; + + /** + * Update an object used to track property names within object initializers + * and class bodies. Produce warnings in response to duplicated names. + * + * @param {object} props - a collection of all properties of the object or + * class to which the current property is being + * assigned + * @param {string} name - the property name + * @param {object} tkn - the token defining the property + * @param {boolean} [isClass] - whether the accessor is part of an ES6 Class + * definition + * @param {boolean} [isStatic] - whether the accessor is a static method + * @param {boolean} [isComputed] - whether the property is a computed expression like [Symbol.iterator] + */ + function saveProperty(props, name, tkn, isClass, isStatic, isComputed) { + if (tkn.identifier) { + name = tkn.value; + } + var key = name; + if (isClass && isStatic) { + key = "static " + name; } - // Final value is either NoSubstTemplate or TemplateTail - tokenType = tokenType === Token.TemplateHead ? Token.NoSubstTemplate : Token.TemplateTail; - this.skip(1); - this.templateStarts.pop(); + if (props[key] && name !== "__proto__" && !isComputed) { + var msg = ["key", "class method", "static class method"]; + msg = msg[(isClass || false) + (isStatic || false)]; + warning("W075", state.tokens.next, msg, name); + } else { + props[key] = Object.create(null); + } - return { - type: tokenType, - value: value, - startLine: startLine, - startChar: startChar, - isUnclosed: false, - depth: depth, - context: this.popContext() - }; - }, + props[key].basic = true; + props[key].basictkn = tkn; + } - /* - * Extract a string out of the next sequence of characters and/or - * lines or return 'null' if its not possible. Since strings can - * span across multiple lines this method has to move the char - * pointer. - * - * This method recognizes pseudo-multiline JavaScript strings: + /** + * Update an object used to track property names within object initializers + * and class bodies. Produce warnings in response to duplicated names. * - * var str = "hello\ - * world"; + * @param {string} accessorType - Either "get" or "set" + * @param {object} props - a collection of all properties of the object or + * class to which the current accessor is being + * assigned + * @param {object} tkn - the identifier token representing the accessor name + * @param {boolean} [isClass] - whether the accessor is part of an ES6 Class + * definition + * @param {boolean} [isStatic] - whether the accessor is a static method */ - scanStringLiteral: function(checks) { - /*jshint loopfunc:true */ - var quote = this.peek(); - - // String must start with a quote. - if (quote !== "\"" && quote !== "'") { - return null; + function saveAccessor(accessorType, props, name, tkn, isClass, isStatic) { + var flagName = accessorType === "get" ? "getterToken" : "setterToken"; + var key = name; + state.tokens.curr.accessorType = accessorType; + state.nameStack.set(tkn); + if (isClass && isStatic) { + key = "static " + name; } - // In JSON strings must always use double quotes. - this.triggerAsync("warning", { - code: "W108", - line: this.line, - character: this.char // +1? - }, checks, function() { return state.jsonMode && quote !== "\""; }); - - var value = ""; - var startLine = this.line; - var startChar = this.char; - var allowNewLine = false; - - this.skip(); - - while (this.peek() !== quote) { - if (this.peek() === "") { // End Of Line - - // If an EOL is not preceded by a backslash, show a warning - // and proceed like it was a legit multi-line string where - // author simply forgot to escape the newline symbol. - // - // Another approach is to implicitly close a string on EOL - // but it generates too many false positives. - - if (!allowNewLine) { - this.trigger("warning", { - code: "W112", - line: this.line, - character: this.char - }); + if (props[key]) { + if ((props[key].basic || props[key][flagName]) && name !== "__proto__") { + var msg = ""; + if (isClass) { + if (isStatic) { + msg += "static "; + } + msg += accessorType + "ter method"; } else { - allowNewLine = false; - - // Otherwise show a warning if multistr option was not set. - // For JSON, show warning no matter what. - - this.triggerAsync("warning", { - code: "W043", - line: this.line, - character: this.char - }, checks, function() { return !state.option.multistr; }); - - this.triggerAsync("warning", { - code: "W042", - line: this.line, - character: this.char - }, checks, function() { return state.jsonMode && state.option.multistr; }); - } - - // If we get an EOF inside of an unclosed string, show an - // error and implicitly close it at the EOF point. - - if (!this.nextLine()) { - this.trigger("error", { - code: "E029", - line: startLine, - character: startChar - }); - - return { - type: Token.StringLiteral, - value: value, - startLine: startLine, - startChar: startChar, - isUnclosed: true, - quote: quote - }; - } - - } else { // Any character other than End Of Line - - allowNewLine = false; - var char = this.peek(); - var jump = 1; // A length of a jump, after we're done - // parsing this character. - - if (char < " ") { - // Warn about a control character in a string. - this.trigger("warning", { - code: "W113", - line: this.line, - character: this.char, - data: [ "" ] - }); + msg = "key"; } - - // Special treatment for some escaped characters. - if (char === "\\") { - var parsed = this.scanEscapeSequence(checks); - char = parsed.char; - jump = parsed.jump; - allowNewLine = parsed.allowNewLine; - } - - value += char; - this.skip(jump); + warning("W075", state.tokens.next, msg, name); } + } else { + props[key] = Object.create(null); } - this.skip(); - return { - type: Token.StringLiteral, - value: value, - startLine: startLine, - startChar: startChar, - isUnclosed: false, - quote: quote - }; - }, + props[key][flagName] = tkn; + if (isStatic) { + props[key].static = true; + } + } - /* - * Extract a regular expression out of the next sequence of - * characters and/or lines or return 'null' if its not possible. + /** + * Parse a computed property name within object initializers and class bodies + * as introduced by ES2015. For example: * - * This method is platform dependent: it accepts almost any - * regular expression values but then tries to compile and run - * them using system's RegExp object. This means that there are - * rare edge cases where one JavaScript engine complains about - * your regular expression while others don't. + * void { + * [object.method()]: null + * }; + * + * @param {number} context - the parsing context + * + * @returns {object} - the token value that describes the expression which + * defines the property name */ - scanRegExp: function() { - var index = 0; - var length = this.input.length; - var char = this.peek(); - var value = char; - var body = ""; - var flags = []; - var malformed = false; - var isCharSet = false; - var terminated; - - var scanUnexpectedChars = function() { - // Unexpected control character - if (char < " ") { - malformed = true; - this.trigger("warning", { - code: "W048", - line: this.line, - character: this.char - }); - } + function computedPropertyName(context) { + advance("["); - // Unexpected escaped character - if (char === "<") { - malformed = true; - this.trigger("warning", { - code: "W049", - line: this.line, - character: this.char, - data: [ char ] - }); - } - }.bind(this); + // Explicitly reclassify token as a delimeter to prevent its later + // interpretation as an "infix" operator. + state.tokens.curr.delim = true; + state.tokens.curr.lbp = 0; - // Regular expressions must start with '/' - if (!this.prereg || char !== "/") { - return null; + if (!state.inES6()) { + warning("W119", state.tokens.curr, "computed property names", "6"); } + var value = expression(context & ~prodParams.noin, 10); + advance("]"); + return value; + } - index += 1; - terminated = false; - - // Try to get everything in between slashes. A couple of - // cases aside (see scanUnexpectedChars) we don't really - // care whether the resulting expression is valid or not. - // We will check that later using the RegExp object. - - while (index < length) { - char = this.peek(index); - value += char; - body += char; - - if (isCharSet) { - if (char === "]") { - if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") { - isCharSet = false; - } - } + /** + * Test whether a given token is a punctuator whose `value` property matches + * one of the specified values. This function explicitly verifies the token's + * `type` property so that like-valued string literals (e.g. `";"`) do not + * produce false positives. + * + * @param {Token} token + * @param {Array.} values + * + * @returns {boolean} + */ + function checkPunctuators(token, values) { + if (token.type === "(punctuator)") { + return _.includes(values, token.value); + } + return false; + } - if (char === "\\") { - index += 1; - char = this.peek(index); - body += char; - value += char; + /** + * Test whether a given token is a punctuator whose `value` property matches + * the specified value. This function explicitly verifies the token's `type` + * property so that like-valued string literals (e.g. `";"`) do not produce + * false positives. + * + * @param {Token} token + * @param {string} value + * + * @returns {boolean} + */ + function checkPunctuator(token, value) { + return token.type === "(punctuator)" && token.value === value; + } - scanUnexpectedChars(); - } + // Check whether this function has been reached for a destructuring assign with undeclared values + function destructuringAssignOrJsonValue(context) { + // lookup for the assignment (ECMAScript 6 only) + // if it has semicolons, it is a block, so go parse it as a block + // or it's not a block, but there are assignments, check for undeclared variables - index += 1; - continue; + var block = lookupBlockType(); + if (block.notJson) { + if (!state.inES6() && block.isDestAssign) { + /* istanbul ignore next */ + warning("W104", state.tokens.curr, "destructuring assignment", "6"); } + statements(context); + // otherwise parse json value + } else { + state.option.laxbreak = true; + state.jsonMode = true; + jsonValue(); + } + } - if (char === "\\") { - index += 1; - char = this.peek(index); - body += char; - value += char; - - scanUnexpectedChars(); - - if (char === "/") { - index += 1; - continue; - } - - if (char === "[") { - index += 1; - continue; + /** + * Parse and define the three states of a list comprehension in order to + * avoid defining global variables, but keeping them to the list + * comprehension scope only. The order of the states are as follows: + * + * - "use" - which will be the returned iterative part of the list + * comprehension + * - "define" - which will define the variables local to the list + * comprehension + * - "filter" - which will help filter out values + */ + var arrayComprehension = function() { + var CompArray = function() { + this.mode = "use"; + this.variables = []; + }; + var _carrays = []; + var _current; + function declare(v) { + var l = _current.variables.filter(function(elt) { + // if it has, change its undef state + if (elt.value === v) { + elt.undef = false; + return v; } - } - - if (char === "[") { - isCharSet = true; - index += 1; - continue; - } - - if (char === "/") { - body = body.substr(0, body.length - 1); - terminated = true; - index += 1; - break; - } - - index += 1; + }).length; + return l !== 0; } - - // A regular expression that was never closed is an - // error from which we cannot recover. - - if (!terminated) { - this.trigger("error", { - code: "E015", - line: this.line, - character: this.from - }); - - return void this.trigger("fatal", { - line: this.line, - from: this.from - }); + function use(v) { + var l = _current.variables.filter(function(elt) { + // and if it has been defined + if (elt.value === v && !elt.undef) { + if (elt.unused === true) { + elt.unused = false; + } + return v; + } + }).length; + // otherwise we warn about it + return (l === 0); } + return { stack: function() { + _current = new CompArray(); + _carrays.push(_current); + }, + unstack: function() { + _current.variables.filter(function(v) { + if (v.unused) + warning("W098", v.token, v.token.raw_text || v.value); + if (v.undef) + state.funct["(scope)"].block.use(v.value, v.token); + }); + _carrays.splice(-1, 1); + _current = _carrays[_carrays.length - 1]; + }, + setState: function(s) { + if (_.includes(["use", "define", "generate", "filter"], s)) + _current.mode = s; + }, + check: function(v) { + if (!_current) { + return; + } + // When we are in "use" state of the list comp, we enqueue that var + if (_current && _current.mode === "use") { + if (use(v)) { + _current.variables.push({ + token: state.tokens.curr, + value: v, + undef: true, + unused: false + }); + } + return true; + // When we are in "define" state of the list comp, + } else if (_current && _current.mode === "define") { + // check if the variable has been used previously + if (!declare(v)) { + _current.variables.push({ + token: state.tokens.curr, + value: v, + undef: false, + unused: true + }); + } + return true; + // When we are in the "generate" state of the list comp, + } else if (_current && _current.mode === "generate") { + state.funct["(scope)"].block.use(v, state.tokens.curr); + return true; + // When we are in "filter" state, + } else if (_current && _current.mode === "filter") { + // we check whether current variable has been declared + if (use(v)) { + // if not we warn about it + /* istanbul ignore next */ + state.funct["(scope)"].block.use(v, state.tokens.curr); + } + return true; + } + /* istanbul ignore next */ + return false; + } + }; + }; - // Parse flags (if any). - while (index < length) { - char = this.peek(index); - if (!/[gim]/.test(char)) { - break; + /** + * Parse input according to the JSON format. + * + * http://json.org/ + */ + function jsonValue() { + function jsonObject() { + var o = {}, t = state.tokens.next; + advance("{"); + if (state.tokens.next.id !== "}") { + for (;;) { + if (state.tokens.next.id === "(end)") { + error("E026", state.tokens.next, t.line); + } else if (state.tokens.next.id === "}") { + warning("W094", state.tokens.curr); + break; + } else if (state.tokens.next.id === ",") { + error("E028", state.tokens.next); + } else if (state.tokens.next.id !== "(string)") { + warning("W095", state.tokens.next, state.tokens.next.value); + } + if (o[state.tokens.next.value] === true) { + warning("W075", state.tokens.next, "key", state.tokens.next.value); + } else if ((state.tokens.next.value === "__proto__" && + !state.option.proto) || (state.tokens.next.value === "__iterator__" && + !state.option.iterator)) { + warning("W096", state.tokens.next, state.tokens.next.value); + } else { + o[state.tokens.next.value] = true; + } + advance(); + advance(":"); + jsonValue(); + if (state.tokens.next.id !== ",") { + break; + } + advance(","); + } } - flags.push(char); - value += char; - index += 1; + advance("}"); } - // Check regular expression for correctness. - - try { - new RegExp(body, flags.join("")); - } catch (err) { - malformed = true; - this.trigger("error", { - code: "E016", - line: this.line, - character: this.char, - data: [ err.message ] // Platform dependent! - }); + function jsonArray() { + var t = state.tokens.next; + advance("["); + if (state.tokens.next.id !== "]") { + for (;;) { + if (state.tokens.next.id === "(end)") { + error("E027", state.tokens.next, t.line); + } else if (state.tokens.next.id === "]") { + warning("W094", state.tokens.curr); + break; + } else if (state.tokens.next.id === ",") { + error("E028", state.tokens.next); + } + jsonValue(); + if (state.tokens.next.id !== ",") { + break; + } + advance(","); + } + } + advance("]"); } - return { - type: Token.RegExp, - value: value, - flags: flags, - isMalformed: malformed - }; - }, - - /* - * Scan for any occurrence of non-breaking spaces. Non-breaking spaces - * can be mistakenly typed on OS X with option-space. Non UTF-8 web - * pages with non-breaking pages produce syntax errors. - */ - scanNonBreakingSpaces: function() { - return state.option.nonbsp ? - this.input.search(/(\u00A0)/) : -1; - }, + switch (state.tokens.next.id) { + case "{": + jsonObject(); + break; + case "[": + jsonArray(); + break; + case "true": + case "false": + case "null": + case "(number)": + case "(string)": + advance(); + break; + case "-": + advance("-"); + advance("(number)"); + break; + default: + error("E003", state.tokens.next); + } + } - /* - * Scan for characters that get silently deleted by one or more browsers. + /** + * Lint dynamically-evaluated code, appending any resulting errors/warnings + * into the global `errors` array. + * + * @param {array} internals - collection of "internals" objects describing + * string tokens that contain evaluated code + * @param {object} options - linting options to apply + * @param {object} globals - globally-defined bindings for the evaluated code */ - scanUnsafeChars: function() { - return this.input.search(reg.unsafeChars); - }, + function lintEvalCode(internals, options, globals) { + var priorErrorCount, idx, jdx, internal; - /* - * Produce the next raw token or return 'null' if no tokens can be matched. - * This method skips over all space characters. - */ - next: function(checks) { - this.from = this.char; + for (idx = 0; idx < internals.length; idx += 1) { + internal = internals[idx]; + options.scope = internal.elem; + priorErrorCount = JSHINT.errors.length; - // Move to the next non-space character. - var start; - if (/\s/.test(this.peek())) { - start = this.char; + itself(internal.code, options, globals); - while (/\s/.test(this.peek())) { - this.from += 1; - this.skip(); + for (jdx = priorErrorCount; jdx < JSHINT.errors.length; jdx += 1) { + JSHINT.errors[jdx].line += internal.token.line - 1; } } + } - // Methods that work with multi-line structures and move the - // character pointer. + var escapeRegex = function(str) { + return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); + }; - var match = this.scanComments() || - this.scanStringLiteral(checks) || - this.scanTemplateLiteral(checks); + // The actual JSHINT function itself. + var itself = function(s, o, g) { + var x, reIgnoreStr, reIgnore; + var optionKeys, newOptionObj, newIgnoredObj; - if (match) { - return match; - } - - // Methods that don't move the character pointer. - - match = - this.scanRegExp() || - this.scanPunctuator() || - this.scanKeyword() || - this.scanIdentifier() || - this.scanNumericLiteral(); + o = _.clone(o); + state.reset(); + newOptionObj = state.option; + newIgnoredObj = state.ignored; - if (match) { - this.skip(match.tokenLength || match.value.length); - return match; + if (o && o.scope) { + JSHINT.scope = o.scope; + } else { + JSHINT.errors = []; + JSHINT.internals = []; + JSHINT.blacklist = {}; + JSHINT.scope = "(main)"; } - // No token could be matched, give up. + predefined = Object.create(null); + combine(predefined, vars.ecmaIdentifiers[3]); + combine(predefined, vars.reservedVars); - return null; - }, + declared = Object.create(null); + var exported = Object.create(null); // Variables that live outside the current file - /* - * Switch to the next line and reset all char pointers. Once - * switched, this method also checks for other minor warnings. - */ - nextLine: function() { - var char; + function each(obj, cb) { + if (!obj) + return; - if (this.line >= this.getLines().length) { - return false; + if (!Array.isArray(obj) && typeof obj === "object") + obj = Object.keys(obj); + + obj.forEach(cb); } - this.input = this.getLines()[this.line]; - this.line += 1; - this.char = 1; - this.from = 1; + if (o) { - var inputTrimmed = this.input.trim(); + each([o.predef, o.globals], function(dict) { + each(dict, function(item) { + var slice, prop; - var startsWith = function() { - return _.some(arguments, function(prefix) { - return inputTrimmed.indexOf(prefix) === 0; + if (item[0] === "-") { + slice = item.slice(1); + JSHINT.blacklist[slice] = slice; + // remove from predefined if there + delete predefined[slice]; + } else { + prop = Object.getOwnPropertyDescriptor(dict, item); + predefined[item] = prop ? prop.value : false; + } + }); }); - }; - var endsWith = function() { - return _.some(arguments, function(suffix) { - return inputTrimmed.indexOf(suffix, inputTrimmed.length - suffix.length) !== -1; + each(o.exported || null, function(item) { + exported[item] = true; }); - }; - // If we are ignoring linter errors, replace the input with empty string - // if it doesn't already at least start or end a multi-line comment - if (this.ignoringLinterErrors === true) { - if (!startsWith("/*", "//") && !(this.inComment && endsWith("*/"))) { - this.input = ""; + delete o.predef; + delete o.exported; + + optionKeys = Object.keys(o); + for (x = 0; x < optionKeys.length; x++) { + if (/^-W\d{3}$/g.test(optionKeys[x])) { + newIgnoredObj[optionKeys[x].slice(1)] = true; + } else { + var optionKey = optionKeys[x]; + newOptionObj[optionKey] = o[optionKey]; + } } } - char = this.scanNonBreakingSpaces(); - if (char >= 0) { - this.trigger("warning", { code: "W125", line: this.line, character: char + 1 }); - } + state.option = newOptionObj; + state.ignored = newIgnoredObj; - this.input = this.input.replace(/\t/g, state.tab); - char = this.scanUnsafeChars(); + state.option.indent = state.option.indent || 4; + state.option.maxerr = state.option.maxerr || 50; - if (char >= 0) { - this.trigger("warning", { code: "W100", line: this.line, character: char }); - } + indent = 1; - // If there is a limit on line length, warn when lines get too - // long. + var scopeManagerInst = scopeManager(state, predefined, exported, declared); + scopeManagerInst.on("warning", function(ev) { + warning.apply(null, [ ev.code, ev.token].concat(ev.data)); + }); - if (!this.ignoringLinterErrors && state.option.maxlen && - state.option.maxlen < this.input.length) { - var inComment = this.inComment || - startsWith.call(inputTrimmed, "//") || - startsWith.call(inputTrimmed, "/*"); + scopeManagerInst.on("error", function(ev) { + /* istanbul ignore next */ + error.apply(null, [ ev.code, ev.token ].concat(ev.data)); + }); - var shouldTriggerError = !inComment || !reg.maxlenException.test(inputTrimmed); + state.funct = functor("(global)", null, { + "(global)" : true, + "(scope)" : scopeManagerInst, + "(comparray)" : arrayComprehension(), + "(metrics)" : createMetrics(state.tokens.next) + }); - if (shouldTriggerError) { - this.trigger("warning", { code: "W101", line: this.line, character: this.input.length }); - } + functions = [state.funct]; + member = {}; + membersOnly = null; + inblock = false; + lookahead = []; + + if (!isString(s) && !Array.isArray(s)) { + errorAt("E004", 0); + return false; } - return true; - }, + api = { + get isJSON() { + /* istanbul ignore next */ + return state.jsonMode; + }, - /* - * This is simply a synonym for nextLine() method with a friendlier - * public name. - */ - start: function() { - this.nextLine(); - }, + getOption: function(name) { + return state.option[name] || null; + }, - /* - * Produce the next token. This function is called by advance() to get - * the next token. It returns a token in a JSLint-compatible format. - */ - token: function() { - /*jshint loopfunc:true */ - var checks = asyncTrigger(); - var token; + getCache: function(name) { + return state.cache[name]; + }, + + setCache: function(name, value) { + state.cache[name] = value; + }, + warn: function(code, data) { + warningAt.apply(null, [ code, data.line, data.char ].concat(data.data)); + }, - function isReserved(token, isProperty) { - if (!token.reserved) { - return false; + on: function(names, listener) { + names.split(" ").forEach(function(name) { + emitter.on(name, listener); + }.bind(this)); } - var meta = token.meta; + }; - if (meta && meta.isFutureReservedWord && state.inES5()) { - // ES3 FutureReservedWord in an ES5 environment. - if (!meta.es5) { - return false; - } + emitter.removeAllListeners(); + (extraModules || []).forEach(function(func) { + func(api); + }); - // Some ES5 FutureReservedWord identifiers are active only - // within a strict mode environment. - if (meta.strictOnly) { - if (!state.option.strict && !state.isStrict()) { - return false; - } - } + state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"]; + if (o && o.ignoreDelimiters) { - if (isProperty) { - return false; - } + if (!Array.isArray(o.ignoreDelimiters)) { + /* istanbul ignore next */ + o.ignoreDelimiters = [o.ignoreDelimiters]; } - return true; + o.ignoreDelimiters.forEach(function(delimiterPair) { + if (!delimiterPair.start || !delimiterPair.end) + return; + + reIgnoreStr = escapeRegex(delimiterPair.start) + + "[\\s\\S]*?" + + escapeRegex(delimiterPair.end); + + reIgnore = new RegExp(reIgnoreStr, "ig"); + + s = s.replace(reIgnore, function(match) { + return match.replace(/./g, " "); + }); + }); } - // Produce a token object. - var create = function(type, value, isProperty, token) { - /*jshint validthis:true */ - var obj; + lex = new Lexer(s); - if (type !== "(endline)" && type !== "(end)") { - this.prereg = false; - } + lex.on("warning", function(ev) { + warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data)); + }); - if (type === "(punctuator)") { - switch (value) { - case ".": - case ")": - case "~": - case "#": - case "]": - case "++": - case "--": - this.prereg = false; - break; - default: - this.prereg = true; - } + lex.on("error", function(ev) { + errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data)); + }); - obj = Object.create(state.syntax[value] || state.syntax["(error)"]); - } + lex.on("fatal", function(ev) { + quit("E041", ev); + }); - if (type === "(identifier)") { - if (value === "return" || value === "case" || value === "typeof") { - this.prereg = true; + lex.on("Identifier", function(ev) { + emitter.emit("Identifier", ev); + }); + + lex.on("String", function(ev) { + emitter.emit("String", ev); + }); + + lex.on("Number", function(ev) { + emitter.emit("Number", ev); + }); + + // Check options + var name; + for (name in o) { + if (_.has(o, name)) { + checkOption(name, true, state.tokens.curr); + } + } + if (o) { + for (name in o.unstable) { + if (_.has(o.unstable, name)) { + checkOption(name, false, state.tokens.curr); } + } + } - if (_.has(state.syntax, value)) { - obj = Object.create(state.syntax[value] || state.syntax["(error)"]); + try { + applyOptions(); + + // combine the passed globals after we've assumed all our options + combine(predefined, g || {}); + + //reset values + checkComma.first = true; + + advance(); + switch (state.tokens.next.id) { + case "{": + case "[": + destructuringAssignOrJsonValue(0); + break; + default: + directives(); - // If this can't be a reserved keyword, reset the object. - if (!isReserved(obj, isProperty && type === "(identifier)")) { - obj = null; + if (state.directive["use strict"]) { + if (!state.allowsGlobalUsd()) { + warning("W097", state.directive["use strict"]); } } + + statements(0); } - if (!obj) { - obj = Object.create(state.syntax[type]); + if (state.tokens.next.id !== "(end)") { + quit("E041", state.tokens.curr); } - obj.identifier = (type === "(identifier)"); - obj.type = obj.type || type; - obj.value = value; - obj.line = this.line; - obj.character = this.char; - obj.from = this.from; - if (obj.identifier && token) obj.raw_text = token.text || token.value; - if (token && token.startLine && token.startLine !== this.line) { - obj.startLine = token.startLine; - } - if (token && token.context) { - // Context of current token - obj.context = token.context; - } - if (token && token.depth) { - // Nested template depth - obj.depth = token.depth; - } - if (token && token.isUnclosed) { - // Mark token as unclosed string / template literal - obj.isUnclosed = token.isUnclosed; - } + state.funct["(scope)"].unstack(); - if (isProperty && obj.identifier) { - obj.isProperty = isProperty; + } catch (err) { + if (err && err.name === "JSHintError") { + var nt = state.tokens.next || {}; + JSHINT.errors.push({ + scope : "(main)", + raw : err.raw, + code : err.code, + reason : err.reason, + line : err.line || nt.line, + character : err.character || nt.from + }); + } else { + /* istanbul ignore next */ + throw err; } + } - obj.check = checks.check; - - return obj; - }.bind(this); - - for (;;) { - if (!this.input.length) { - if (this.nextLine()) { - return create("(endline)", ""); - } + // Loop over the listed "internals", and check them as well. + if (JSHINT.scope === "(main)") { + lintEvalCode(JSHINT.internals, o || {}, g); + } - if (this.exhausted) { - return null; - } + return JSHINT.errors.length === 0; + }; - this.exhausted = true; - return create("(end)", ""); - } + // Modules. + itself.addModule = function(func) { + extraModules.push(func); + }; - token = this.next(checks); + itself.addModule(style.register); - if (!token) { - if (this.input.length) { - // Unexpected character. - this.trigger("error", { - code: "E024", - line: this.line, - character: this.char, - data: [ this.peek() ] - }); + // Data summary. + itself.data = function() { + var data = { + functions: [], + options: state.option + }; - this.input = ""; - } + var fu, f, i, n, globals; - continue; - } + if (itself.errors.length) { + data.errors = itself.errors; + } - switch (token.type) { - case Token.StringLiteral: - this.triggerAsync("String", { - line: this.line, - char: this.char, - from: this.from, - startLine: token.startLine, - startChar: token.startChar, - value: token.value, - quote: token.quote - }, checks, function() { return true; }); + if (state.jsonMode) { + /* istanbul ignore next */ + data.json = true; + } - return create("(string)", token.value, null, token); + var impliedGlobals = state.funct["(scope)"].getImpliedGlobals(); + if (impliedGlobals.length > 0) { + data.implieds = impliedGlobals; + } - case Token.TemplateHead: - this.trigger("TemplateHead", { - line: this.line, - char: this.char, - from: this.from, - startLine: token.startLine, - startChar: token.startChar, - value: token.value - }); - return create("(template)", token.value, null, token); + globals = state.funct["(scope)"].getUsedOrDefinedGlobals(); + if (globals.length > 0) { + data.globals = globals; + } - case Token.TemplateMiddle: - this.trigger("TemplateMiddle", { - line: this.line, - char: this.char, - from: this.from, - startLine: token.startLine, - startChar: token.startChar, - value: token.value - }); - return create("(template middle)", token.value, null, token); + for (i = 1; i < functions.length; i += 1) { + f = functions[i]; + fu = {}; - case Token.TemplateTail: - this.trigger("TemplateTail", { - line: this.line, - char: this.char, - from: this.from, - startLine: token.startLine, - startChar: token.startChar, - value: token.value - }); - return create("(template tail)", token.value, null, token); + fu.name = f["(name)"]; + fu.param = f["(params)"]; + fu.line = f["(line)"]; + fu.character = f["(character)"]; + fu.last = f["(last)"]; + fu.lastcharacter = f["(lastcharacter)"]; - case Token.NoSubstTemplate: - this.trigger("NoSubstTemplate", { - line: this.line, - char: this.char, - from: this.from, - startLine: token.startLine, - startChar: token.startChar, - value: token.value - }); - return create("(no subst template)", token.value, null, token); + fu.metrics = { + complexity: f["(metrics)"].ComplexityCount, + parameters: f["(metrics)"].arity, + statements: f["(metrics)"].statementCount + }; - case Token.Identifier: - this.triggerAsync("Identifier", { - line: this.line, - char: this.char, - from: this.form, - name: token.value, - raw_name: token.text, - isProperty: state.tokens.curr.id === "." - }, checks, function() { return true; }); + data.functions.push(fu); + } - /* falls through */ - case Token.Keyword: - case Token.NullLiteral: - case Token.BooleanLiteral: - return create("(identifier)", token.value, state.tokens.curr.id === ".", token); + var unuseds = state.funct["(scope)"].getUnuseds(); + if (unuseds.length > 0) { + data.unused = unuseds; + } - case Token.NumericLiteral: - if (token.isMalformed) { - this.trigger("warning", { - code: "W045", - line: this.line, - character: this.char, - data: [ token.value ] - }); - } + for (n in member) { + if (typeof member[n] === "number") { + data.member = member; + break; + } + } - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "0x-" ] - }, checks, function() { return token.base === 16 && state.jsonMode; }); + return data; + }; - this.triggerAsync("warning", { - code: "W115", - line: this.line, - character: this.char - }, checks, function() { - return state.isStrict() && token.base === 8 && token.isLegacy; - }); + itself.jshint = itself; - this.trigger("Number", { - line: this.line, - char: this.char, - from: this.from, - value: token.value, - base: token.base, - isMalformed: token.malformed - }); + return itself; +}()); - return create("(number)", token.value); +// Make JSHINT a Node module, if possible. +if (typeof exports === "object" && exports) { + exports.JSHINT = JSHINT; +} - case Token.RegExp: - return create("(regexp)", token.value); +},{"./lex.js":"/../../../jshint/src/lex.js","./messages.js":"/../../../jshint/src/messages.js","./options.js":"/../../../jshint/src/options.js","./prod-params.js":"/../../../jshint/src/prod-params.js","./reg.js":"/../../../jshint/src/reg.js","./scope-manager.js":"/../../../jshint/src/scope-manager.js","./state.js":"/../../../jshint/src/state.js","./style.js":"/../../../jshint/src/style.js","./vars.js":"/../../../jshint/src/vars.js","console-browserify":"/../../../jshint/node_modules/console-browserify/index.js","events":"/node_modules/events/events.js","lodash.clone":"/../../../jshint/node_modules/lodash.clone/index.js","underscore":"/../../../jshint/node_modules/underscore/underscore-umd.js"}],"/../../../jshint/src/lex.js":[function(_dereq_,module,exports){ +/* + * Lexical analysis and token construction. + */ - case Token.Comment: - state.tokens.curr.comment = true; +"use strict"; - if (token.isSpecial) { - return { - id: '(comment)', - value: token.value, - body: token.body, - type: token.commentType, - isSpecial: token.isSpecial, - line: this.line, - character: this.char, - from: this.from - }; - } +var _ = _dereq_("underscore"); +var events = _dereq_("events"); +var reg = _dereq_("./reg.js"); +var state = _dereq_("./state.js").state; - break; +var unicodeData = _dereq_("../data/ascii-identifier-data.js"); +var asciiIdentifierStartTable = unicodeData.asciiIdentifierStartTable; +var asciiIdentifierPartTable = unicodeData.asciiIdentifierPartTable; +var nonAsciiIdentifierStartTable = _dereq_("../data/non-ascii-identifier-start.js"); +var nonAsciiIdentifierPartTable = _dereq_("../data/non-ascii-identifier-part-only.js"); +// Loading of this module is deferred as an optimization for ES2015 input +var es5IdentifierNames; - case "": - break; +// Some of these token types are from JavaScript Parser API +// while others are specific to JSHint parser. +// JS Parser API: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API - default: - return create("(punctuator)", token.value); +var Token = { + Identifier: 1, + Punctuator: 2, + NumericLiteral: 3, + StringLiteral: 4, + Comment: 5, + Keyword: 6, + RegExp: 9, + TemplateHead: 10, + TemplateMiddle: 11, + TemplateTail: 12, + NoSubstTemplate: 13 +}; + +var Context = { + Block: 1, + Template: 2 +}; + +function isHex(str) { + return /^[0-9a-fA-F]+$/.test(str); +} + +function isHexDigit(str) { + return str.length === 1 && isHex(str); +} + +// Object that handles postponed lexing verifications that checks the parsed +// environment state. + +function asyncTrigger() { + var _checks = []; + + return { + push: function(fn) { + _checks.push(fn); + }, + + check: function() { + for (var check = 0; check < _checks.length; ++check) { + _checks[check](); } + + _checks.splice(0, _checks.length); } + }; +} + +/* + * Lexer for JSHint. + * + * This object does a char-by-char scan of the provided source code + * and produces a sequence of tokens. + * + * var lex = new Lexer("var i = 0;"); + * lex.start(); + * lex.token(); // returns the next token + * + * You have to use the token() method to move the lexer forward + * but you don't have to use its return value to get tokens. In addition + * to token() method returning the next token, the Lexer object also + * emits events. + * + * lex.on("Identifier", function(data) { + * if (data.name.indexOf("_") >= 0) { + * // Produce a warning. + * } + * }); + * + * Note that the token() method returns tokens in a JSLint-compatible + * format while the event emitter uses a slightly modified version of + * Mozilla's JavaScript Parser API. Eventually, we will move away from + * JSLint format. + */ +function Lexer(source) { + var lines = source; + + if (typeof lines === "string") { + lines = lines + .replace(/\r\n/g, "\n") + .replace(/\r/g, "\n") + .split("\n"); } -}; -exports.Lexer = Lexer; -exports.Context = Context; + // If the first line is a shebang (#!), make it a blank and move on. + // Shebangs are used by Node scripts. -},{"../data/ascii-identifier-data.js":"/node_modules/jshint/data/ascii-identifier-data.js","../lodash":"/node_modules/jshint/lodash.js","./reg.js":"/node_modules/jshint/src/reg.js","./state.js":"/node_modules/jshint/src/state.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/messages.js":[function(_dereq_,module,exports){ -"use strict"; + if (lines[0] && lines[0].substr(0, 2) === "#!") { + if (lines[0].indexOf("node") !== -1) { + state.option.node = true; + } + lines[0] = ""; + } -var _ = _dereq_("../lodash"); + this.emitter = new events.EventEmitter(); + this.source = source; + this.setLines(lines); + this.prereg = true; -var errors = { - // JSHint options - E001: "Bad option: '{a}'.", - E002: "Bad option value.", + this.line = 0; + this.char = 1; + this.from = 1; + this.input = ""; + this.inComment = false; + this.context = []; + this.templateStarts = []; - // JSHint input - E003: "Expected a JSON value.", - E004: "Input is neither a string nor an array of strings.", - E005: "Input is empty.", - E006: "Unexpected early end of program.", + for (var i = 0; i < state.option.indent; i += 1) { + state.tab += " "; + } +} - // Strict mode - E007: "Missing \"use strict\" statement.", - E008: "Strict violation.", - E009: "Option 'validthis' can't be used in a global scope.", - E010: "'with' is not allowed in strict mode.", +Lexer.prototype = { + _lines: [], - // Constants - E011: "'{a}' has already been declared.", - E012: "const '{a}' is initialized to 'undefined'.", - E013: "Attempting to override '{a}' which is a constant.", + inContext: function(ctxType) { + return this.context.length > 0 && this.context[this.context.length - 1].type === ctxType; + }, - // Regular expressions - E014: "A regular expression literal can be confused with '/='.", - E015: "Unclosed regular expression.", - E016: "Invalid regular expression.", + pushContext: function(ctxType) { + this.context.push({ type: ctxType }); + }, - // Tokens - E017: "Unclosed comment.", - E018: "Unbegun comment.", - E019: "Unmatched '{a}'.", - E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", - E021: "Expected '{a}' and instead saw '{b}'.", - E022: "Line breaking error '{a}'.", - E023: "Missing '{a}'.", - E024: "Unexpected '{a}'.", - E025: "Missing ':' on a case clause.", - E026: "Missing '}' to match '{' from line {a}.", - E027: "Missing ']' to match '[' from line {a}.", - E028: "Illegal comma.", - E029: "Unclosed string.", + popContext: function() { + return this.context.pop(); + }, - // Everything else - E030: "Expected an identifier and instead saw '{a}'.", - E031: "Bad assignment.", // FIXME: Rephrase - E032: "Expected a small integer or 'false' and instead saw '{a}'.", - E033: "Expected an operator and instead saw '{a}'.", - E034: "get/set are ES5 features.", - E035: "Missing property name.", - E036: "Expected to see a statement and instead saw a block.", - E037: null, - E038: null, - E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.", - E040: "Each value should have its own case label.", - E041: "Unrecoverable syntax error.", - E042: "Stopping.", - E043: "Too many errors.", - E044: null, - E045: "Invalid for each loop.", - E046: "A yield statement shall be within a generator function (with syntax: `function*`)", - E047: null, - E048: "{a} declaration not directly within block.", - E049: "A {a} cannot be named '{b}'.", - E050: "Mozilla requires the yield expression to be parenthesized here.", - E051: null, - E052: "Unclosed template literal.", - E053: "Export declaration must be in global scope.", - E054: "Class properties must be methods. Expected '(' but instead saw '{a}'.", - E055: "The '{a}' option cannot be set after any executable code.", - E056: "'{a}' was used before it was declared, which is illegal for '{b}' variables.", - E057: "Invalid meta property: '{a}.{b}'.", - E058: "Missing semicolon." -}; + currentContext: function() { + return this.context.length > 0 && this.context[this.context.length - 1]; + }, -var warnings = { - W001: "'hasOwnProperty' is a really bad name.", - W002: "Value of '{a}' may be overwritten in IE 8 and earlier.", - W003: "'{a}' was used before it was defined.", - W004: "'{a}' is already defined.", - W005: "A dot following a number can be confused with a decimal point.", - W006: "Confusing minuses.", - W007: "Confusing plusses.", - W008: "A leading decimal point can be confused with a dot: '{a}'.", - W009: "The array literal notation [] is preferable.", - W010: "The object literal notation {} is preferable.", - W011: null, - W012: null, - W013: null, - W014: "Bad line breaking before '{a}'.", - W015: null, - W016: "Unexpected use of '{a}'.", - W017: "Bad operand.", - W018: "Confusing use of '{a}'.", - W019: "Use the isNaN function to compare with NaN.", - W020: "Read only.", - W021: "Reassignment of '{a}', which is is a {b}. " + - "Use 'var' or 'let' to declare bindings that may change.", - W022: "Do not assign to the exception parameter.", - W023: "Expected an identifier in an assignment and instead saw a function invocation.", - W024: "Expected an identifier and instead saw '{a}' (a reserved word).", - W025: "Missing name in function declaration.", - W026: "Inner functions should be listed at the top of the outer function.", - W027: "Unreachable '{a}' after '{b}'.", - W028: "Label '{a}' on {b} statement.", - W030: "Expected an assignment or function call and instead saw an expression.", - W031: "Do not use 'new' for side effects.", - W032: "Unnecessary semicolon.", - W033: "Missing semicolon.", - W034: "Unnecessary directive \"{a}\".", - W035: "Empty block.", - W036: "Unexpected /*member '{a}'.", - W037: "'{a}' is a statement label.", - W038: "'{a}' used out of scope.", - W039: "'{a}' is not allowed.", - W040: "Possible strict violation.", - W041: "Use '{a}' to compare with '{b}'.", - W042: "Avoid EOL escaping.", - W043: "Bad escaping of EOL. Use option multistr if needed.", - W044: "Bad or unnecessary escaping.", /* TODO(caitp): remove W044 */ - W045: "Bad number '{a}'.", - W046: "Don't use extra leading zeros '{a}'.", - W047: "A trailing decimal point can be confused with a dot: '{a}'.", - W048: "Unexpected control character in regular expression.", - W049: "Unexpected escaped character '{a}' in regular expression.", - W050: "JavaScript URL.", - W051: "Variables should not be deleted.", - W052: "Unexpected '{a}'.", - W053: "Do not use {a} as a constructor.", - W054: "The Function constructor is a form of eval.", - W055: "A constructor name should start with an uppercase letter.", - W056: "Bad constructor.", - W057: "Weird construction. Is 'new' necessary?", - W058: "Missing '()' invoking a constructor.", - W059: "Avoid arguments.{a}.", - W060: "document.write can be a form of eval.", - W061: "eval can be harmful.", - W062: "Wrap an immediate function invocation in parens " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself.", - W063: "Math is not a function.", - W064: "Missing 'new' prefix when invoking a constructor.", - W065: "Missing radix parameter.", - W066: "Implied eval. Consider passing a function instead of a string.", - W067: "Bad invocation.", - W068: "Wrapping non-IIFE function literals in parens is unnecessary.", - W069: "['{a}'] is better written in dot notation.", - W070: "Extra comma. (it breaks older versions of IE)", - W071: "This function has too many statements. ({a})", - W072: "This function has too many parameters. ({a})", - W073: "Blocks are nested too deeply. ({a})", - W074: "This function's cyclomatic complexity is too high. ({a})", - W075: "Duplicate {a} '{b}'.", - W076: "Unexpected parameter '{a}' in get {b} function.", - W077: "Expected a single parameter in set {a} function.", - W078: "Setter is defined without getter.", - W079: "Redefinition of '{a}'.", - W080: "It's not necessary to initialize '{a}' to 'undefined'.", - W081: null, - W082: "Function declarations should not be placed in blocks. " + - "Use a function expression or move the statement to the top of " + - "the outer function.", - W083: "Don't make functions within a loop.", - W084: "Assignment in conditional expression", - W085: "Don't use 'with'.", - W086: "Expected a 'break' statement before '{a}'.", - W087: "Forgotten 'debugger' statement?", - W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.", - W089: "The body of a for in should be wrapped in an if statement to filter " + - "unwanted properties from the prototype.", - W090: "'{a}' is not a statement label.", - W091: null, - W093: "Did you mean to return a conditional instead of an assignment?", - W094: "Unexpected comma.", - W095: "Expected a string and instead saw {a}.", - W096: "The '{a}' key may produce unexpected results.", - W097: "Use the function form of \"use strict\".", - W098: "'{a}' is defined but never used.", - W099: null, - W100: "This character may get silently deleted by one or more browsers.", - W101: "Line is too long.", - W102: null, - W103: "The '{a}' property is deprecated.", - W104: "'{a}' is available in ES{b} (use 'esversion: {b}') or Mozilla JS extensions (use moz).", - W105: "Unexpected {a} in '{b}'.", - W106: "Identifier '{a}' is not in camel case.", - W107: "Script URL.", - W108: "Strings must use doublequote.", - W109: "Strings must use singlequote.", - W110: "Mixed double and single quotes.", - W112: "Unclosed string.", - W113: "Control character in string: {a}.", - W114: "Avoid {a}.", - W115: "Octal literals are not allowed in strict mode.", - W116: "Expected '{a}' and instead saw '{b}'.", - W117: "'{a}' is not defined.", - W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).", - W119: "'{a}' is only available in ES{b} (use 'esversion: {b}').", - W120: "You might be leaking a variable ({a}) here.", - W121: "Extending prototype of native object: '{a}'.", - W122: "Invalid typeof value '{a}'", - W123: "'{a}' is already defined in outer scope.", - W124: "A generator function shall contain a yield statement.", - W125: "This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp", - W126: "Unnecessary grouping operator.", - W127: "Unexpected use of a comma operator.", - W128: "Empty array elements require elision=true.", - W129: "'{a}' is defined in a future version of JavaScript. Use a " + - "different variable name to avoid migration issues.", - W130: "Invalid element after rest element.", - W131: "Invalid parameter after rest parameter.", - W132: "`var` declarations are forbidden. Use `let` or `const` instead.", - W133: "Invalid for-{a} loop left-hand-side: {b}.", - W134: "The '{a}' option is only available when linting ECMAScript {b} code.", - W135: "{a} may not be supported by non-browser environments.", - W136: "'{a}' must be in function scope.", - W137: "Empty destructuring.", - W138: "Regular parameters should not come after default parameters." -}; + getLines: function() { + this._lines = state.lines; + return this._lines; + }, -var info = { - I001: "Comma warnings can be turned off with 'laxcomma'.", - I002: null, - I003: "ES5 option is now set per default" -}; + setLines: function(val) { + this._lines = val; + state.lines = this._lines; + }, -exports.errors = {}; -exports.warnings = {}; -exports.info = {}; + /* + * Return the next i character without actually moving the + * char pointer. + */ + peek: function(i) { + return this.input.charAt(i || 0); + }, -_.each(errors, function(desc, code) { - exports.errors[code] = { code: code, desc: desc }; -}); + /* + * Move the char pointer forward i times. + */ + skip: function(i) { + i = i || 1; + this.char += i; + this.input = this.input.slice(i); + }, -_.each(warnings, function(desc, code) { - exports.warnings[code] = { code: code, desc: desc }; -}); + /* + * Subscribe to a token event. The API for this method is similar + * Underscore.js i.e. you can subscribe to multiple events with + * one call: + * + * lex.on("Identifier Number", function(data) { + * // ... + * }); + */ + on: function(names, listener) { + names.split(" ").forEach(function(name) { + this.emitter.on(name, listener); + }.bind(this)); + }, -_.each(info, function(desc, code) { - exports.info[code] = { code: code, desc: desc }; -}); + /* + * Trigger a token event. All arguments will be passed to each + * listener. + */ + trigger: function() { + this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments)); + }, -},{"../lodash":"/node_modules/jshint/lodash.js"}],"/node_modules/jshint/src/name-stack.js":[function(_dereq_,module,exports){ -"use strict"; + /* + * Postpone a token event. the checking condition is set as + * last parameter, and the trigger function is called in a + * stored callback. To be later called using the check() function + * by the parser. This avoids parser's peek() to give the lexer + * a false context. + */ + triggerAsync: function(type, args, checks, fn) { + checks.push(function() { + if (fn()) { + this.trigger(type, args); + } + }.bind(this)); + }, -function NameStack() { - this._stack = []; -} + /* + * Extract a punctuator out of the next sequence of characters + * or return 'null' if its not possible. + * + * This method's implementation was heavily influenced by the + * scanPunctuator function in the Esprima parser's source code. + */ + scanPunctuator: function() { + var ch1 = this.peek(); + var ch2, ch3, ch4; -Object.defineProperty(NameStack.prototype, "length", { - get: function() { - return this._stack.length; - } -}); + switch (ch1) { + // Most common single-character punctuators + case ".": + if ((/^[0-9]$/).test(this.peek(1))) { + return null; + } + if (this.peek(1) === "." && this.peek(2) === ".") { + return { + type: Token.Punctuator, + value: "..." + }; + } + /* falls through */ + case "(": + case ")": + case ";": + case ",": + case "[": + case "]": + case ":": + case "~": + return { + type: Token.Punctuator, + value: ch1 + }; -/** - * Create a new entry in the stack. Useful for tracking names across - * expressions. - */ -NameStack.prototype.push = function() { - this._stack.push(null); -}; + // A block/object opener + case "{": + this.pushContext(Context.Block); + return { + type: Token.Punctuator, + value: ch1 + }; -/** - * Discard the most recently-created name on the stack. - */ -NameStack.prototype.pop = function() { - this._stack.pop(); -}; + // A block/object closer + case "}": + if (this.inContext(Context.Block)) { + this.popContext(); + } + return { + type: Token.Punctuator, + value: ch1 + }; -/** - * Update the most recent name on the top of the stack. - * - * @param {object} token The token to consider as the source for the most - * recent name. - */ -NameStack.prototype.set = function(token) { - this._stack[this.length - 1] = token; -}; + // A pound sign (for Node shebangs) + case "#": + return { + type: Token.Punctuator, + value: ch1 + }; -/** - * Generate a string representation of the most recent name. - * - * @returns {string} - */ -NameStack.prototype.infer = function() { - var nameToken = this._stack[this.length - 1]; - var prefix = ""; - var type; + // We're at the end of input + case "": + return null; + } - // During expected operation, the topmost entry on the stack will only - // reflect the current function's name when the function is declared without - // the `function` keyword (i.e. for in-line accessor methods). In other - // cases, the `function` expression itself will introduce an empty entry on - // the top of the stack, and this should be ignored. - if (!nameToken || nameToken.type === "class") { - nameToken = this._stack[this.length - 2]; - } + // Peek more characters - if (!nameToken) { - return "(empty)"; - } + ch2 = this.peek(1); + ch3 = this.peek(2); - type = nameToken.type; + if (ch1 === "?") { + // Optional chaining + if (ch2 === "." && !reg.decimalDigit.test(ch3)) { + return { + type: Token.Punctuator, + value: "?." + }; + } - if (type !== "(string)" && type !== "(number)" && type !== "(identifier)" && type !== "default") { - return "(expression)"; - } + return { + type: Token.Punctuator, + value: ch2 === "?" ? "??" : "?" + }; + } - if (nameToken.accessorType) { - prefix = nameToken.accessorType + " "; - } + ch4 = this.peek(3); - return prefix + nameToken.value; -}; + // 4-character punctuator: >>>= -module.exports = NameStack; + if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") { + return { + type: Token.Punctuator, + value: ">>>=" + }; + } -},{}],"/node_modules/jshint/src/options.js":[function(_dereq_,module,exports){ -"use strict"; + // 3-character punctuators: === !== >>> <<= >>= -// These are the JSHint boolean options. -exports.bool = { - enforcing: { + if (ch1 === "=" && ch2 === "=" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "===" + }; + } - /** - * This option prohibits the use of bitwise operators such as `^` (XOR), - * `|` (OR) and others. Bitwise operators are very rare in JavaScript - * programs and quite often `&` is simply a mistyped `&&`. - */ - bitwise : true, + if (ch1 === "!" && ch2 === "=" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "!==" + }; + } - /** - * - * This options prohibits overwriting prototypes of native objects such as - * `Array`, `Date` and so on. - * - * // jshint freeze:true - * Array.prototype.count = function (value) { return 4; }; - * // -> Warning: Extending prototype of native object: 'Array'. - */ - freeze : true, + if (ch1 === ">" && ch2 === ">" && ch3 === ">") { + return { + type: Token.Punctuator, + value: ">>>" + }; + } - /** - * This option allows you to force all variable names to use either - * camelCase style or UPPER_CASE with underscores. - * - * @deprecated JSHint is limiting its scope to issues of code correctness. - * If you would like to enforce rules relating to code style, - * check out [the JSCS - * project](https://github.com/jscs-dev/node-jscs). - */ - camelcase : true, + if (ch1 === "<" && ch2 === "<" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "<<=" + }; + } - /** - * This option requires you to always put curly braces around blocks in - * loops and conditionals. JavaScript allows you to omit curly braces when - * the block consists of only one statement, for example: - * - * while (day) - * shuffle(); - * - * However, in some circumstances, it can lead to bugs (you'd think that - * `sleep()` is a part of the loop while in reality it is not): - * - * while (day) - * shuffle(); - * sleep(); - */ - curly : true, + if (ch1 === ">" && ch2 === ">" && ch3 === "=") { + return { + type: Token.Punctuator, + value: ">>=" + }; + } - /** - * This options prohibits the use of `==` and `!=` in favor of `===` and - * `!==`. The former try to coerce values before comparing them which can - * lead to some unexpected results. The latter don't do any coercion so - * they are generally safer. If you would like to learn more about type - * coercion in JavaScript, we recommend [Truth, Equality and - * JavaScript](http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/) - * by Angus Croll. - */ - eqeqeq : true, + // Fat arrow punctuator + if (ch1 === "=" && ch2 === ">") { + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } - /** - * This option enables warnings about the use of identifiers which are - * defined in future versions of JavaScript. Although overwriting them has - * no effect in contexts where they are not implemented, this practice can - * cause issues when migrating codebases to newer versions of the language. - */ - futurehostile: true, + // 2-character punctuators: ++ -- << >> && || ** + if (ch1 === ch2 && ("+-<>&|*".indexOf(ch1) >= 0)) { + if (ch1 === "*" && ch3 === "=") { + return { + type: Token.Punctuator, + value: ch1 + ch2 + ch3 + }; + } - /** - * This option suppresses warnings about invalid `typeof` operator values. - * This operator has only [a limited set of possible return - * values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof). - * By default, JSHint warns when you compare its result with an invalid - * value which often can be a typo. - * - * // 'fuction' instead of 'function' - * if (typeof a == "fuction") { // Invalid typeof value 'fuction' - * // ... - * } - * - * Do not use this option unless you're absolutely sure you don't want - * these checks. - */ - notypeof : true, + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } - /** - * This option tells JSHint that your code needs to adhere to ECMAScript 3 - * specification. Use this option if you need your program to be executable - * in older browsers—such as Internet Explorer 6/7/8/9—and other legacy - * JavaScript environments. - * - * @deprecated Use `esversion: 3` instead. - */ - es3 : true, + // <= >= != += -= *= %= &= |= ^= /= + if ("<>=!+-*%&|^/".indexOf(ch1) >= 0) { + if (ch2 === "=") { + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } - /** - * This option enables syntax first defined in [the ECMAScript 5.1 - * specification](http://es5.github.io/). This includes allowing reserved - * keywords as object properties. - * - * @deprecated Use `esversion: 5` instead. - */ - es5 : true, + return { + type: Token.Punctuator, + value: ch1 + }; + } - /** - * This option requires all `for in` loops to filter object's items. The - * for in statement allows for looping through the names of all of the - * properties of an object including those inherited through the prototype - * chain. This behavior can lead to unexpected items in your object so it - * is generally safer to always filter inherited properties out as shown in - * the example: - * - * for (key in obj) { - * if (obj.hasOwnProperty(key)) { - * // We are sure that obj[key] belongs to the object and was not inherited. - * } - * } - * - * For more in-depth understanding of `for in` loops in JavaScript, read - * [Exploring JavaScript for-in - * loops](http://javascriptweblog.wordpress.com/2011/01/04/exploring-javascript-for-in-loops/) - * by Angus Croll. - */ - forin : true, + return null; + }, - /** - * This option suppresses warnings about declaring variables inside of - * control - * structures while accessing them later from the outside. Even though - * JavaScript has only two real scopes—global and function—such practice - * leads to confusion among people new to the language and hard-to-debug - * bugs. This is why, by default, JSHint warns about variables that are - * used outside of their intended scope. - * - * function test() { - * if (true) { - * var x = 0; - * } - * - * x += 1; // Default: 'x' used out of scope. - * // No warning when funcscope:true - * } - */ - funcscope : true, + /* + * Extract a comment out of the next sequence of characters and/or + * lines or return 'null' if its not possible. Since comments can + * span across multiple lines this method has to move the char + * pointer. + * + * In addition to normal JavaScript comments (// and /*) this method + * also recognizes JSHint- and JSLint-specific comments such as + * /*jshint, /*jslint, /*globals and so on. + */ + scanComments: function(checks) { + var ch1 = this.peek(); + var ch2 = this.peek(1); + var rest = this.input.substr(2); + var startLine = this.line; + var startChar = this.char; + var self = this; - /** - * This option prohibits the use of immediate function invocations without - * wrapping them in parentheses. Wrapping parentheses assists readers of - * your code in understanding that the expression is the result of a - * function, and not the function itself. - * - * @deprecated JSHint is limiting its scope to issues of code correctness. - * If you would like to enforce rules relating to code style, - * check out [the JSCS - * project](https://github.com/jscs-dev/node-jscs). - */ - immed : true, + // Create a comment token object and make sure it + // has all the data JSHint needs to work with special + // comments. - /** - * This option suppresses warnings about the `__iterator__` property. This - * property is not supported by all browsers so use it carefully. - */ - iterator : true, + function commentToken(label, body, opt) { + var special = [ + "jshint", "jshint.unstable", "jslint", "members", "member", "globals", + "global", "exported" + ]; + var isSpecial = false; + var value = label + body; + var commentType = "plain"; + opt = opt || {}; - /** - * This option requires you to capitalize names of constructor functions. - * Capitalizing functions that are intended to be used with `new` operator - * is just a convention that helps programmers to visually distinguish - * constructor functions from other types of functions to help spot - * mistakes when using `this`. - * - * Not doing so won't break your code in any browsers or environments but - * it will be a bit harder to figure out—by reading the code—if the - * function was supposed to be used with or without new. And this is - * important because when the function that was intended to be used with - * `new` is used without it, `this` will point to the global object instead - * of a new object. - * - * @deprecated JSHint is limiting its scope to issues of code correctness. - * If you would like to enforce rules relating to code style, - * check out [the JSCS - * project](https://github.com/jscs-dev/node-jscs). - */ - newcap : true, - - /** - * This option prohibits the use of `arguments.caller` and - * `arguments.callee`. Both `.caller` and `.callee` make quite a few - * optimizations impossible so they were deprecated in future versions of - * JavaScript. In fact, ECMAScript 5 forbids the use of `arguments.callee` - * in strict mode. - */ - noarg : true, + if (opt.isMultiline) { + value += "*/"; + } - /** - * This option prohibits the use of the comma operator. When misused, the - * comma operator can obscure the value of a statement and promote - * incorrect code. - */ - nocomma : true, + body = body.replace(/\n/g, " "); - /** - * This option warns when you have an empty block in your code. JSLint was - * originally warning for all empty blocks and we simply made it optional. - * There were no studies reporting that empty blocks in JavaScript break - * your code in any way. - * - * @deprecated JSHint is limiting its scope to issues of code correctness. - * If you would like to enforce rules relating to code style, - * check out [the JSCS - * project](https://github.com/jscs-dev/node-jscs). - */ - noempty : true, + if (label === "/*" && reg.fallsThrough.test(body)) { + isSpecial = true; + commentType = "falls through"; + } - /** - * This option warns about "non-breaking whitespace" characters. These - * characters can be entered with option-space on Mac computers and have a - * potential of breaking non-UTF8 web pages. - */ - nonbsp : true, + special.forEach(function(str) { + if (isSpecial) { + return; + } - /** - * This option prohibits the use of constructor functions for side-effects. - * Some people like to call constructor functions without assigning its - * result to any variable: - * - * new MyConstructor(); - * - * There is no advantage in this approach over simply calling - * `MyConstructor` since the object that the operator `new` creates isn't - * used anywhere so you should generally avoid constructors like this one. - */ - nonew : true, + // Don't recognize any special comments other than jshint for single-line + // comments. This introduced many problems with legit comments. + if (label === "//" && str !== "jshint" && str !== "jshint.unstable") { + return; + } - /** - * This option prohibits the use of explicitly undeclared variables. This - * option is very useful for spotting leaking and mistyped variables. - * - * // jshint undef:true - * - * function test() { - * var myVar = 'Hello, World'; - * console.log(myvar); // Oops, typoed here. JSHint with undef will complain - * } - * - * If your variable is defined in another file, you can use the `global` - * directive to tell JSHint about it. - */ - undef : true, + if (body.charAt(str.length) === " " && body.substr(0, str.length) === str) { + isSpecial = true; + label = label + str; + body = body.substr(str.length); + } - /** - * This option prohibits the use of the grouping operator when it is not - * strictly required. Such usage commonly reflects a misunderstanding of - * unary operators, for example: - * - * // jshint singleGroups: true - * - * delete(obj.attr); // Warning: Unnecessary grouping operator. - */ - singleGroups: false, + if (!isSpecial && body.charAt(0) === " " && body.charAt(str.length + 1) === " " && + body.substr(1, str.length) === str) { + isSpecial = true; + label = label + " " + str; + body = body.substr(str.length + 1); + } - /** - * When set to true, the use of VariableStatements are forbidden. - * For example: - * - * // jshint varstmt: true - * - * var a; // Warning: `var` declarations are forbidden. Use `let` or `const` instead. - */ - varstmt: false, + // To handle rarer case when special word is separated from label by + // multiple spaces or tabs + var strIndex = body.indexOf(str); + if (!isSpecial && strIndex >= 0 && body.charAt(strIndex + str.length) === " ") { + var isAllWhitespace = body.substr(0, strIndex).trim().length === 0; + if (isAllWhitespace) { + isSpecial = true; + body = body.substr(str.length + strIndex); + } + } - /** - * This option is a short hand for the most strict JSHint configuration as - * available in JSHint version 2.6.3. It enables all enforcing options and - * disables all relaxing options that were defined in that release. - * - * @deprecated The option cannot be maintained without automatically opting - * users in to new features. This can lead to unexpected - * warnings/errors in when upgrading between minor versions of - * JSHint. - */ - enforceall : false - }, - relaxing: { + if (!isSpecial) { + return; + } - /** - * This option suppresses warnings about missing semicolons. There is a lot - * of FUD about semicolon spread by quite a few people in the community. - * The common myths are that semicolons are required all the time (they are - * not) and that they are unreliable. JavaScript has rules about semicolons - * which are followed by *all* browsers so it is up to you to decide - * whether you should or should not use semicolons in your code. - * - * For more information about semicolons in JavaScript read [An Open Letter - * to JavaScript Leaders Regarding - * Semicolons](http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding) - * by Isaac Schlueter and [JavaScript Semicolon - * Insertion](http://inimino.org/~inimino/blog/javascript_semicolons). - */ - asi : true, + switch (str) { + case "member": + commentType = "members"; + break; + case "global": + commentType = "globals"; + break; + default: + var options = body.split(":").map(function(v) { + return v.replace(/^\s+/, "").replace(/\s+$/, ""); + }); - /** - * This option suppresses warnings about multi-line strings. Multi-line - * strings can be dangerous in JavaScript because all hell breaks loose if - * you accidentally put a whitespace in between the escape character (`\`) - * and a new line. - * - * Note that even though this option allows correct multi-line strings, it - * still warns about multi-line strings without escape characters or with - * anything in between the escape character and a whitespace. - * - * // jshint multistr:true - * - * var text = "Hello\ - * World"; // All good. - * - * text = "Hello - * World"; // Warning, no escape character. - * - * text = "Hello\ - * World"; // Warning, there is a space after \ - * - * @deprecated JSHint is limiting its scope to issues of code correctness. - * If you would like to enforce rules relating to code style, - * check out [the JSCS - * project](https://github.com/jscs-dev/node-jscs). - */ - multistr : true, + if (options.length === 2) { + switch (options[0]) { + case "ignore": + switch (options[1]) { + case "start": + self.ignoringLinterErrors = true; + isSpecial = false; + break; + case "end": + self.ignoringLinterErrors = false; + isSpecial = false; + break; + } + } + } - /** - * This option suppresses warnings about the `debugger` statements in your - * code. - */ - debug : true, + commentType = str; + } + }); - /** - * This option suppresses warnings about the use of assignments in cases - * where comparisons are expected. More often than not, code like `if (a = - * 10) {}` is a typo. However, it can be useful in cases like this one: - * - * for (var i = 0, person; person = people[i]; i++) {} - * - * You can silence this error on a per-use basis by surrounding the assignment - * with parenthesis, such as: - * - * for (var i = 0, person; (person = people[i]); i++) {} - */ - boss : true, + return { + type: Token.Comment, + commentType: commentType, + value: value, + body: body, + isSpecial: isSpecial, + isMalformed: opt.isMalformed || false + }; + } - /** - * This option suppresses warnings about the use of `eval`. The use of - * `eval` is discouraged because it can make your code vulnerable to - * various injection attacks and it makes it hard for JavaScript - * interpreter to do certain optimizations. - */ - evil : true, + // End of unbegun comment. Raise an error and skip that input. + if (ch1 === "*" && ch2 === "/") { + this.trigger("error", { + code: "E018", + line: startLine, + character: startChar + }); - /** - * This option suppresses warnings about the use of global strict mode. - * Global strict mode can break third-party widgets so it is not - * recommended. - * - * For more info about strict mode see the `strict` option. - * - * @deprecated Use `strict: "global"`. - */ - globalstrict: true, + this.skip(2); + return null; + } - /** - * This option prohibits the use of unary increment and decrement - * operators. Some people think that `++` and `--` reduces the quality of - * their coding styles and there are programming languages—such as - * Python—that go completely without these operators. - */ - plusplus : true, + // Comments must start either with // or /* + if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) { + return null; + } - /** - * This option suppresses warnings about the `__proto__` property. - */ - proto : true, + // One-line comment + if (ch2 === "/") { + this.skip(this.input.length); // Skip to the EOL. + return commentToken("//", rest); + } - /** - * This option suppresses warnings about the use of script-targeted - * URLs—such as `javascript:...`. - */ - scripturl : true, + var body = ""; - /** - * This option suppresses warnings about using `[]` notation when it can be - * expressed in dot notation: `person['name']` vs. `person.name`. - * - * @deprecated JSHint is limiting its scope to issues of code correctness. - * If you would like to enforce rules relating to code style, - * check out [the JSCS - * project](https://github.com/jscs-dev/node-jscs). - */ - sub : true, + /* Multi-line comment */ + if (ch2 === "*") { + this.inComment = true; + this.skip(2); - /** - * This option suppresses warnings about "weird" constructions like - * `new function () { ... }` and `new Object;`. Such constructions are - * sometimes used to produce singletons in JavaScript: - * - * var singleton = new function() { - * var privateVar; - * - * this.publicMethod = function () {} - * this.publicMethod2 = function () {} - * }; - */ - supernew : true, + while (this.peek() !== "*" || this.peek(1) !== "/") { + if (this.peek() === "") { // End of Line + body += "\n"; - /** - * This option suppresses most of the warnings about possibly unsafe line - * breakings in your code. It doesn't suppress warnings about comma-first - * coding style. To suppress those you have to use `laxcomma` (see below). - * - * @deprecated JSHint is limiting its scope to issues of code correctness. - * If you would like to enforce rules relating to code style, - * check out [the JSCS - * project](https://github.com/jscs-dev/node-jscs). - */ - laxbreak : true, + // If we hit EOF and our comment is still unclosed, + // trigger an error and end the comment implicitly. + if (!this.nextLine(checks)) { + this.trigger("error", { + code: "E017", + line: startLine, + character: startChar + }); - /** - * This option suppresses warnings about comma-first coding style: - * - * var obj = { - * name: 'Anton' - * , handle: 'valueof' - * , role: 'SW Engineer' - * }; - * - * @deprecated JSHint is limiting its scope to issues of code correctness. - * If you would like to enforce rules relating to code style, - * check out [the JSCS - * project](https://github.com/jscs-dev/node-jscs). - */ - laxcomma : true, + this.inComment = false; + return commentToken("/*", body, { + isMultiline: true, + isMalformed: true + }); + } + } else { + body += this.peek(); + this.skip(); + } + } - /** - * This option suppresses warnings about possible strict violations when - * the code is running in strict mode and you use `this` in a - * non-constructor function. You should use this option—in a function scope - * only—when you are positive that your use of `this` is valid in the - * strict mode (for example, if you call your function using - * `Function.call`). - * - * **Note:** This option can be used only inside of a function scope. - * JSHint will fail with an error if you will try to set this option - * globally. - */ - validthis : true, + this.skip(2); + this.inComment = false; + return commentToken("/*", body, { isMultiline: true }); + } + }, - /** - * This option suppresses warnings about the use of the `with` statement. - * The semantics of the `with` statement can cause confusion among - * developers and accidental definition of global variables. - * - * More info: - * - * * [with Statement Considered - * Harmful](http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/) - */ - withstmt : true, + /* + * Extract a keyword out of the next sequence of characters or + * return 'null' if its not possible. + */ + scanKeyword: function() { + var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input); + var keywords = [ + "if", "in", "do", "var", "for", "new", + "try", "let", "this", "else", "case", + "void", "with", "enum", "while", "break", + "catch", "throw", "const", "yield", "class", + "super", "return", "typeof", "delete", + "switch", "export", "import", "default", + "finally", "extends", "function", "continue", + "debugger", "instanceof", "true", "false", "null", "async", "await" + ]; - /** - * This options tells JSHint that your code uses Mozilla JavaScript - * extensions. Unless you develop specifically for the Firefox web browser - * you don't need this option. - * - * More info: - * - * * [New in JavaScript - * 1.7](https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.7) - */ - moz : true, + if (result && keywords.indexOf(result[0]) >= 0) { + return { + type: Token.Keyword, + value: result[0] + }; + } - /** - * This option suppresses warnings about generator functions with no - * `yield` statement in them. - */ - noyield : true, + return null; + }, - /** - * This option suppresses warnings about `== null` comparisons. Such - * comparisons are often useful when you want to check if a variable is - * `null` or `undefined`. - */ - eqnull : true, + /* + * Extract a JavaScript identifier out of the next sequence of + * characters or return 'null' if its not possible. + */ + scanIdentifier: function(checks) { + var id = ""; + var index = 0; + var char, value; - /** - * This option suppresses warnings about missing semicolons, but only when - * the semicolon is omitted for the last statement in a one-line block: - * - * var name = (function() { return 'Anton' }()); - * - * This is a very niche use case that is useful only when you use automatic - * JavaScript code generators. - */ - lastsemic : true, + function isNonAsciiIdentifierStart(code) { + return nonAsciiIdentifierStartTable.indexOf(code) > -1; + } - /** - * This option suppresses warnings about functions inside of loops. - * Defining functions inside of loops can lead to bugs such as this one: - * - * var nums = []; - * - * for (var i = 0; i < 10; i++) { - * nums[i] = function (j) { - * return i + j; - * }; - * } - * - * nums[0](2); // Prints 12 instead of 2 - * - * To fix the code above you need to copy the value of `i`: - * - * var nums = []; - * - * for (var i = 0; i < 10; i++) { - * (function (i) { - * nums[i] = function (j) { - * return i + j; - * }; - * }(i)); - * } - */ - loopfunc : true, + function isNonAsciiIdentifierPart(code) { + return isNonAsciiIdentifierStart(code) || nonAsciiIdentifierPartTable.indexOf(code) > -1; + } - /** - * This option suppresses warnings about the use of expressions where - * normally you would expect to see assignments or function calls. Most of - * the time, such code is a typo. However, it is not forbidden by the spec - * and that's why this warning is optional. - */ - expr : true, + var readUnicodeEscapeSequence = function() { + /*jshint validthis:true */ + index += 1; - /** - * This option tells JSHint that your code uses ECMAScript 6 specific - * syntax. Note that these features are not finalized yet and not all - * browsers implement them. - * - * More info: - * - * * [Specification for ECMAScript - * 6](http://www.ecma-international.org/ecma-262/6.0/index.html) - * - * @deprecated Use `esversion: 6` instead. - */ - esnext : true, + if (this.peek(index) !== "u") { + return null; + } - /** - * This option tells JSHint that your code uses ES3 array elision elements, - * or empty elements (for example, `[1, , , 4, , , 7]`). - */ - elision : true, - }, + var sequence = this.peek(index + 1) + this.peek(index + 2) + + this.peek(index + 3) + this.peek(index + 4); + var code; - // Third party globals - environments: { + if (isHex(sequence)) { + code = parseInt(sequence, 16); - /** - * This option defines globals exposed by the - * [MooTools](http://mootools.net/) JavaScript framework. - */ - mootools : true, + if (asciiIdentifierPartTable[code] || isNonAsciiIdentifierPart(code)) { + index += 5; + return "\\u" + sequence; + } - /** - * This option defines globals exposed by - * [CouchDB](http://couchdb.apache.org/). CouchDB is a document-oriented - * database that can be queried and indexed in a MapReduce fashion using - * JavaScript. - */ - couch : true, + return null; + } - /** - * This option defines globals exposed by [the Jasmine unit testing - * framework](https://jasmine.github.io/). - */ - jasmine : true, + return null; + }.bind(this); - /** - * This option defines globals exposed by the [jQuery](http://jquery.com/) - * JavaScript library. - */ - jquery : true, + var getIdentifierStart = function() { + /*jshint validthis:true */ + var chr = this.peek(index); + var code = chr.charCodeAt(0); - /** - * This option defines globals available when your code is running inside - * of the Node runtime environment. [Node.js](http://nodejs.org/) is a - * server-side JavaScript environment that uses an asynchronous - * event-driven model. This option also skips some warnings that make sense - * in the browser environments but don't make sense in Node such as - * file-level `use strict` pragmas and `console.log` statements. - */ - node : true, + if (code === 92) { + return readUnicodeEscapeSequence(); + } - /** - * This option defines globals exposed by [the QUnit unit testing - * framework](http://qunitjs.com/). - */ - qunit : true, + if (code < 128) { + if (asciiIdentifierStartTable[code]) { + index += 1; + return chr; + } - /** - * This option defines globals available when your code is running inside - * of the Rhino runtime environment. [Rhino](http://www.mozilla.org/rhino/) - * is an open-source implementation of JavaScript written entirely in Java. - */ - rhino : true, + return null; + } - /** - * This option defines globals exposed by [the ShellJS - * library](http://documentup.com/arturadib/shelljs). - */ - shelljs : true, + if (isNonAsciiIdentifierStart(code)) { + index += 1; + return chr; + } - /** - * This option defines globals exposed by the - * [Prototype](http://www.prototypejs.org/) JavaScript framework. - */ - prototypejs : true, + return null; + }.bind(this); - /** - * This option defines globals exposed by the [YUI](http://yuilibrary.com/) - * JavaScript framework. - */ - yui : true, + var getIdentifierPart = function() { + /*jshint validthis:true */ + var chr = this.peek(index); + var code = chr.charCodeAt(0); - /** - * This option defines globals exposed by the "BDD" and "TDD" UIs of the - * [Mocha unit testing framework](http://mochajs.org/). - */ - mocha : true, + if (code === 92) { + return readUnicodeEscapeSequence(); + } - /** - * This option informs JSHint that the input code describes an ECMAScript 6 - * module. All module code is interpreted as strict mode code. - */ - module : true, + if (code < 128) { + if (asciiIdentifierPartTable[code]) { + index += 1; + return chr; + } - /** - * This option defines globals available when your code is running as a - * script for the [Windows Script - * Host](http://en.wikipedia.org/wiki/Windows_Script_Host). - */ - wsh : true, + return null; + } - /** - * This option defines globals available when your code is running inside - * of a Web Worker. [Web - * Workers](https://developer.mozilla.org/en/Using_web_workers) provide a - * simple means for web content to run scripts in background threads. - */ - worker : true, + if (isNonAsciiIdentifierPart(code)) { + index += 1; + return chr; + } - /** - * This option defines non-standard but widely adopted globals such as - * `escape` and `unescape`. - */ - nonstandard : true, + return null; + }.bind(this); - /** - * This option defines globals exposed by modern browsers: all the way from - * good old `document` and `navigator` to the HTML5 `FileReader` and other - * new developments in the browser world. - * - * **Note:** This option doesn't expose variables like `alert` or - * `console`. See option `devel` for more information. - */ - browser : true, + function removeEscapeSequences(id) { + return id.replace(/\\u([0-9a-fA-F]{4})/g, function(m0, codepoint) { + return String.fromCharCode(parseInt(codepoint, 16)); + }); + } - /** - * This option defines globals available when using [the Browserify - * tool](http://browserify.org/) to build a project. - */ - browserify : true, + char = getIdentifierStart(); + if (char === null) { + return null; + } - /** - * This option defines globals that are usually used for logging poor-man's - * debugging: `console`, `alert`, etc. It is usually a good idea to not - * ship them in production because, for example, `console.log` breaks in - * legacy versions of Internet Explorer. - */ - devel : true, + id = char; + for (;;) { + char = getIdentifierPart(); - /** - * This option defines globals exposed by the [Dojo - * Toolkit](http://dojotoolkit.org/). - */ - dojo : true, + if (char === null) { + break; + } - /** - * This option defines globals for typed array constructors. - * - * More info: - * - * * [JavaScript typed - * arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - */ - typed : true, + id += char; + } - /** - * This option defines globals available when your core is running inside - * of the PhantomJS runtime environment. [PhantomJS](http://phantomjs.org/) - * is a headless WebKit scriptable with a JavaScript API. It has fast and - * native support for various web standards: DOM handling, CSS selector, - * JSON, Canvas, and SVG. - */ - phantom : true - }, + value = removeEscapeSequences(id); - // Obsolete options - obsolete: { - onecase : true, // if one case switch statements should be allowed - regexp : true, // if the . should not be allowed in regexp literals - regexdash : true // if unescaped first/last dash (-) inside brackets - // should be tolerated - } -}; + if (!state.inES6(true)) { + es5IdentifierNames = _dereq_("../data/es5-identifier-names.js"); -// These are the JSHint options that can take any value -// (we use this object to detect invalid options) -exports.val = { + if (!es5IdentifierNames.test(value)) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: ["unicode 8", "6"] + }, + checks, + function() { return true; } + ); + } + } - /** - * This option lets you set the maximum length of a line. - * - * @deprecated JSHint is limiting its scope to issues of code correctness. If - * you would like to enforce rules relating to code style, check - * out [the JSCS project](https://github.com/jscs-dev/node-jscs). - */ - maxlen : false, + return { + type: Token.Identifier, + value: value, + text: id, + tokenLength: id.length + }; + }, - /** - * This option sets a specific tab width for your code. + /* + * Extract a numeric literal out of the next sequence of + * characters or return 'null' if its not possible. This method + * supports all numeric literals described in section 7.8.3 + * of the EcmaScript 5 specification. * - * @deprecated JSHint is limiting its scope to issues of code correctness. If - * you would like to enforce rules relating to code style, check - * out [the JSCS project](https://github.com/jscs-dev/node-jscs). + * This method's implementation was heavily influenced by the + * scanNumericLiteral function in the Esprima parser's source code. */ - indent : false, + scanNumericLiteral: function(checks) { + var index = 0; + var value = ""; + var length = this.input.length; + var char = this.peek(index); + var isAllowedDigit = isDecimalDigit; + var base = 10; + var isLegacy = false; + var isNonOctal = false; - /** - * This options allows you to set the maximum amount of warnings JSHint will - * produce before giving up. Default is 50. - */ - maxerr : false, + function isDecimalDigit(str) { + return (/^[0-9]$/).test(str); + } - /** - * This option allows you to control which variables JSHint considers to be - * implicitly defined in the environment. Configure it with an array of - * string values. Prefixing a variable name with a hyphen (-) character will - * remove that name from the collection of predefined variables. - * - * JSHint will consider variables declared in this way to be read-only. - * - * This option cannot be specified in-line; it may only be used via the - * JavaScript API or from an external configuration file. - */ - predef : false, + function isOctalDigit(str) { + return (/^[0-7]$/).test(str); + } - /** - * This option can be used to specify a white list of global variables that - * are not formally defined in the source code. This is most useful when - * combined with the `undef` option in order to suppress warnings for - * project-specific global variables. - * - * Setting an entry to `true` enables reading and writing to that variable. - * Setting it to `false` will trigger JSHint to consider that variable - * read-only. - * - * See also the "environment" options: a set of options to be used as short - * hand for enabling global variables defined in common JavaScript - * environments. - * - * To configure `globals` within an individual file, see [Inline - * Configuration](http://jshint.com/docs/#inline-configuration). - */ - globals : false, + function isNonOctalDigit(str) { + return str === "8" || str === "9"; + } - /** - * This option enforces the consistency of quotation marks used throughout - * your code. It accepts three values: `true` if you don't want to enforce - * one particular style but want some consistency, `"single"` if you want to - * allow only single quotes and `"double"` if you want to allow only double - * quotes. - * - * @deprecated JSHint is limiting its scope to issues of code correctness. If - * you would like to enforce rules relating to code style, check - * out [the JSCS project](https://github.com/jscs-dev/node-jscs). - */ - quotmark : false, + function isBinaryDigit(str) { + return (/^[01]$/).test(str); + } - scope : false, + function isIdentifierStart(ch) { + return (ch === "$") || (ch === "_") || (ch === "\\") || + (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z"); + } - /** - * This option lets you set the max number of statements allowed per function: - * - * // jshint maxstatements:4 - * - * function main() { - * var i = 0; - * var j = 0; - * - * // Function declarations count as one statement. Their bodies - * // don't get taken into account for the outer function. - * function inner() { - * var i2 = 1; - * var j2 = 1; - * - * return i2 + j2; - * } - * - * j = i + j; - * return j; // JSHint: Too many statements per function. (5) - * } - */ - maxstatements: false, + // Numbers must start either with a decimal digit or a point. - /** - * This option lets you control how nested do you want your blocks to be: - * - * // jshint maxdepth:2 - * - * function main(meaning) { - * var day = true; - * - * if (meaning === 42) { - * while (day) { - * shuffle(); - * - * if (tired) { // JSHint: Blocks are nested too deeply (3). - * sleep(); - * } - * } - * } - * } - */ - maxdepth : false, + if (char !== "." && !isDecimalDigit(char)) { + return null; + } - /** - * This option lets you set the max number of formal parameters allowed per - * function: - * - * // jshint maxparams:3 - * - * function login(request, onSuccess) { - * // ... - * } - * - * // JSHint: Too many parameters per function (4). - * function logout(request, isManual, whereAmI, onSuccess) { - * // ... - * } - */ - maxparams : false, + if (char !== ".") { + value = this.peek(index); + index += 1; + char = this.peek(index); - /** - * This option lets you control cyclomatic complexity throughout your code. - * Cyclomatic complexity measures the number of linearly independent paths - * through a program's source code. Read more about [cyclomatic complexity on - * Wikipedia](http://en.wikipedia.org/wiki/Cyclomatic_complexity). - */ - maxcomplexity: false, + if (value === "0") { + // Base-16 numbers. + if (char === "x" || char === "X") { + isAllowedDigit = isHexDigit; + base = 16; - /** - * This option suppresses warnings about variable shadowing i.e. declaring a - * variable that had been already declared somewhere in the outer scope. - * - * - "inner" - check for variables defined in the same scope only - * - "outer" - check for variables defined in outer scopes as well - * - false - same as inner - * - true - allow variable shadowing - */ - shadow : false, + index += 1; + value += char; + } - /** - * This option requires the code to run in ECMAScript 5's strict mode. - * [Strict mode](https://developer.mozilla.org/en/JavaScript/Strict_mode) - * is a way to opt in to a restricted variant of JavaScript. Strict mode - * eliminates some JavaScript pitfalls that didn't cause errors by changing - * them to produce errors. It also fixes mistakes that made it difficult - * for the JavaScript engines to perform certain optimizations. - * - * - "func" - there must be a `"use strict";` directive at function level - * - "global" - there must be a `"use strict";` directive at global level - * - "implied" - lint the code as if there is the `"use strict";` directive - * - false - disable warnings about strict mode - * - true - same as `"func"`, but environment options have precedence over - * this (e.g. `node`, `module`, `browserify` and `phantomjs` can - * set `strict: global`) - */ - strict : true, + // Base-8 numbers. + if (char === "o" || char === "O") { + isAllowedDigit = isOctalDigit; + base = 8; - /** - * This option warns when you define and never use your variables. It is very - * useful for general code cleanup, especially when used in addition to - * `undef`. - * - * // jshint unused:true - * - * function test(a, b) { - * var c, d = 2; - * - * return a + d; - * } - * - * test(1, 2); - * - * // Line 3: 'b' was defined but never used. - * // Line 4: 'c' was defined but never used. - * - * In addition to that, this option will warn you about unused global - * variables declared via the `global` directive. - * - * This can be set to `vars` to only check for variables, not function - * parameters, or `strict` to check all variables and parameters. The - * default (true) behavior is to allow unused parameters that are followed by - * a used parameter. - */ - unused : true, + if (!state.inES6(true)) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: [ "Octal integer literal", "6" ] + }, + checks, + function() { return true; } + ); + } - /** - * This option prohibits the use of a variable before it was defined. - * JavaScript has function scope only and, in addition to that, all variables - * are always moved—or hoisted— to the top of the function. This behavior can - * lead to some very nasty bugs and that's why it is safer to always use - * variable only after they have been explicitly defined. - * - * Setting this option to "nofunc" will allow function declarations to be - * ignored. - * - * For more in-depth understanding of scoping and hoisting in JavaScript, - * read [JavaScript Scoping and - * Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting) - * by Ben Cherry. - */ - latedef : false, + index += 1; + value += char; + } - ignore : false, // start/end ignoring lines of code, bypassing the lexer - // start - start ignoring lines, including the current line - // end - stop ignoring lines, starting on the next line - // line - ignore warnings / errors for just a single line - // (this option does not bypass the lexer) + // Base-2 numbers. + if (char === "b" || char === "B") { + isAllowedDigit = isBinaryDigit; + base = 2; - ignoreDelimiters: false, // array of start/end delimiters used to ignore - // certain chunks from code + if (!state.inES6(true)) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: [ "Binary integer literal", "6" ] + }, + checks, + function() { return true; } + ); + } - /** - * This option is used to specify the ECMAScript version to which the code - * must adhere. It can assume one of the following values: - * - `3` - If you need your program to be executable - * in older browsers—such as Internet Explorer 6/7/8/9—and other legacy - * JavaScript environments - * - `5` - To enable syntax first defined in [the ECMAScript 5.1 - * specification](http://www.ecma-international.org/ecma-262/5.1/index.html). - * This includes allowing reserved keywords as object properties. - * - `6` - To tell JSHint that your code uses [ECMAScript - * 6](http://www.ecma-international.org/ecma-262/6.0/index.html) specific - * syntax. Note that not all browsers implement them. - */ - esversion: 5 -}; + index += 1; + value += char; + } -// These are JSHint boolean options which are shared with JSLint -// where the definition in JSHint is opposite JSLint -exports.inverted = { - bitwise : true, - forin : true, - newcap : true, - plusplus: true, - regexp : true, - undef : true, + // Legacy base-8 numbers. + if (isOctalDigit(char)) { + isAllowedDigit = isOctalDigit; + base = 8; + isLegacy = true; - // Inverted and renamed, use JSHint name here - eqeqeq : true, - strict : true -}; + } else if (isDecimalDigit(char)) { + isNonOctal = true; + } + } -exports.validNames = Object.keys(exports.val) - .concat(Object.keys(exports.bool.relaxing)) - .concat(Object.keys(exports.bool.enforcing)) - .concat(Object.keys(exports.bool.obsolete)) - .concat(Object.keys(exports.bool.environments)); + while (index < length) { + char = this.peek(index); -// These are JSHint boolean options which are shared with JSLint -// where the name has been changed but the effect is unchanged -exports.renamed = { - eqeq : "eqeqeq", - windows: "wsh", - sloppy : "strict" -}; - -exports.removed = { - nomen: true, - onevar: true, - passfail: true, - white: true, - gcl: true, - smarttabs: true, - trailing: true -}; - -// Add options here which should not be automatically enforced by -// `enforceall`. -exports.noenforceall = { - varstmt: true, - strict: true -}; - -},{}],"/node_modules/jshint/src/reg.js":[function(_dereq_,module,exports){ -/* - * Regular expressions. Some of these are stupidly long. - */ - -/*jshint maxlen:1000 */ - -"use strict"; - -// Unsafe comment or string (ax) -exports.unsafeString = - /@cc|<\/?|script|\]\s*\]|<\s*!|</i; - -// Unsafe characters that are silently deleted by one or more browsers (cx) -exports.unsafeChars = - /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - -// Characters in strings that need escaping (nx and nxg) -exports.needEsc = - /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - -exports.needEscGlobal = - /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - -// Star slash (lx) -exports.starSlash = /\*\//; - -// Identifier (ix) -exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; - -// JavaScript URL (jx) -exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i; - -// Catches /* falls through */ comments (ft) -exports.fallsThrough = /^\s*falls?\sthrough\s*$/; - -// very conservative rule (eg: only one space between the start of the comment and the first character) -// to relax the maxlen option -exports.maxlenException = /^(?:(?:\/\/|\/\*|\*) ?)?[^ ]+$/; - -},{}],"/node_modules/jshint/src/scope-manager.js":[function(_dereq_,module,exports){ -"use strict"; - -var _ = _dereq_("../lodash"); -var events = _dereq_("events"); - -// Used to denote membership in lookup tables (a primitive value such as `true` -// would be silently rejected for the property name "__proto__" in some -// environments) -var marker = {}; - -/** - * Creates a scope manager that handles variables and labels, storing usages - * and resolving when variables are used and undefined - */ -var scopeManager = function(state, predefined, exported, declared) { - - var _current; - var _scopeStack = []; - - function _newScope(type) { - _current = { - "(labels)": Object.create(null), - "(usages)": Object.create(null), - "(breakLabels)": Object.create(null), - "(parent)": _current, - "(type)": type, - "(params)": (type === "functionparams" || type === "catchparams") ? [] : null - }; - _scopeStack.push(_current); - } - - _newScope("global"); - _current["(predefined)"] = predefined; - - var _currentFunctBody = _current; // this is the block after the params = function - - var usedPredefinedAndGlobals = Object.create(null); - var impliedGlobals = Object.create(null); - var unuseds = []; - var emitter = new events.EventEmitter(); - - function warning(code, token) { - emitter.emit("warning", { - code: code, - token: token, - data: _.slice(arguments, 2) - }); - } - - function error(code, token) { - emitter.emit("warning", { - code: code, - token: token, - data: _.slice(arguments, 2) - }); - } - - function _setupUsages(labelName) { - if (!_current["(usages)"][labelName]) { - _current["(usages)"][labelName] = { - "(modified)": [], - "(reassigned)": [], - "(tokens)": [] - }; - } - } - - var _getUnusedOption = function(unused_opt) { - if (unused_opt === undefined) { - unused_opt = state.option.unused; - } + if (isLegacy && isNonOctalDigit(char)) { + base = 10; + isLegacy = false; + isNonOctal = true; + isAllowedDigit = isDecimalDigit; + } - if (unused_opt === true) { - unused_opt = "last-param"; - } + if (!isAllowedDigit(char)) { + break; + } + value += char; + index += 1; + } - return unused_opt; - }; + var isBigInt = this.peek(index) === 'n'; - var _warnUnused = function(name, tkn, type, unused_opt) { - var line = tkn.line; - var chr = tkn.from; - var raw_name = tkn.raw_text || name; + if (isAllowedDigit !== isDecimalDigit || isBigInt) { + if (isBigInt) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: [ "BigInt", "11" ] + }, + checks, + function() { return !state.inES11(); } + ); + + if (isLegacy || isNonOctal) { + this.triggerAsync( + "error", + { + code: "E067", + line: this.line, + character: this.char, + data: [value + char] + }, + checks, + function() { return true; } + ); + } - unused_opt = _getUnusedOption(unused_opt); + value += char; + index += 1; + } else if (!isLegacy && value.length <= 2) { // 0x + return { + type: Token.NumericLiteral, + value: value, + isMalformed: true + }; + } - var warnable_types = { - "vars": ["var"], - "last-param": ["var", "param"], - "strict": ["var", "param", "last-param"] - }; + if (index < length) { + char = this.peek(index); + if (isIdentifierStart(char)) { + return null; + } + } - if (unused_opt) { - if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) { - warning("W098", { line: line, from: chr }, raw_name); + return { + type: Token.NumericLiteral, + value: value, + base: base, + isLegacy: isLegacy, + isMalformed: false + }; } } - // inconsistent - see gh-1894 - if (unused_opt || type === "var") { - unuseds.push({ - name: name, - line: line, - character: chr - }); - } - }; + // Decimal digits. - /** - * Checks the current scope for unused identifiers - */ - function _checkForUnused() { - // function params are handled specially - // assume that parameters are the only thing declared in the param scope - if (_current["(type)"] === "functionparams") { - _checkParams(); - return; - } - var curentLabels = _current["(labels)"]; - for (var labelName in curentLabels) { - if (curentLabels[labelName]) { - if (curentLabels[labelName]["(type)"] !== "exception" && - curentLabels[labelName]["(unused)"]) { - _warnUnused(labelName, curentLabels[labelName]["(token)"], "var"); + if (char === ".") { + value += char; + index += 1; + + while (index < length) { + char = this.peek(index); + if (!isDecimalDigit(char)) { + break; } + value += char; + index += 1; } } - } - - /** - * Checks the current scope for unused parameters - * Must be called in a function parameter scope - */ - function _checkParams() { - var params = _current["(params)"]; - - if (!params) { - return; - } - - var param = params.pop(); - var unused_opt; - - while (param) { - var label = _current["(labels)"][param]; - unused_opt = _getUnusedOption(state.funct["(unusedOption)"]); + // Exponent part. - // 'undefined' is a special case for (function(window, undefined) { ... })(); - // patterns. - if (param === "undefined") - return; + if (char === "e" || char === "E") { + value += char; + index += 1; + char = this.peek(index); - if (label["(unused)"]) { - _warnUnused(param, label["(token)"], "param", state.funct["(unusedOption)"]); - } else if (unused_opt === "last-param") { - return; + if (char === "+" || char === "-") { + value += this.peek(index); + index += 1; } - param = params.pop(); - } - } + char = this.peek(index); + if (isDecimalDigit(char)) { + value += char; + index += 1; - /** - * Finds the relevant label's scope, searching from nearest outwards - * @returns {Object} the scope the label was found in - */ - function _getLabel(labelName) { - for (var i = _scopeStack.length - 1 ; i >= 0; --i) { - var scopeLabels = _scopeStack[i]["(labels)"]; - if (scopeLabels[labelName]) { - return scopeLabels; + while (index < length) { + char = this.peek(index); + if (!isDecimalDigit(char)) { + break; + } + value += char; + index += 1; + } + } else { + return null; } } - } - function usedSoFarInCurrentFunction(labelName) { - // used so far in this whole function and any sub functions - for (var i = _scopeStack.length - 1; i >= 0; i--) { - var current = _scopeStack[i]; - if (current["(usages)"][labelName]) { - return current["(usages)"][labelName]; - } - if (current === _currentFunctBody) { - break; + if (index < length) { + char = this.peek(index); + if (isIdentifierStart(char)) { + return null; } } - return false; - } - function _checkOuterShadow(labelName, token) { + // TODO: Extend this check to other numeric literals + this.triggerAsync("warning", { + code: "W045", + line: this.line, + character: this.char + value.length, + data: [ value ] + }, checks, function() { return !isFinite(value); }); - // only check if shadow is outer - if (state.option.shadow !== "outer") { - return; - } + return { + type: Token.NumericLiteral, + value: value, + base: base, + isNonOctal: isNonOctal, + isMalformed: false + }; + }, - var isGlobal = _currentFunctBody["(type)"] === "global", - isNewFunction = _current["(type)"] === "functionparams"; - var outsideCurrentFunction = !isGlobal; - for (var i = 0; i < _scopeStack.length; i++) { - var stackItem = _scopeStack[i]; + // Assumes previously parsed character was \ (=== '\\') and was not skipped. + scanEscapeSequence: function(checks) { + var allowNewLine = false; + var jump = 1; + this.skip(); + var char = this.peek(); - if (!isNewFunction && _scopeStack[i + 1] === _currentFunctBody) { - outsideCurrentFunction = false; - } - if (outsideCurrentFunction && stackItem["(labels)"][labelName]) { - warning("W123", token, labelName); - } - if (stackItem["(breakLabels)"][labelName]) { - warning("W123", token, labelName); - } - } - } + switch (char) { + case "'": + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\'" ] + }, checks, function() {return state.jsonMode; }); + break; + case "b": + char = "\\b"; + break; + case "f": + char = "\\f"; + break; + case "n": + char = "\\n"; + break; + case "r": + char = "\\r"; + break; + case "t": + char = "\\t"; + break; + case "0": + char = "\\0"; - function _latedefWarning(type, labelName, token) { - if (state.option.latedef) { - // if either latedef is strict and this is a function - // or this is not a function - if ((state.option.latedef === true && type === "function") || - type !== "function") { - warning("W003", token, labelName); + // Octal literals fail in strict mode. + // Check if the number is between 00 and 07. + var n = parseInt(this.peek(1), 10); + this.triggerAsync("warning", { + code: "W115", + line: this.line, + character: this.char + }, checks, + function() { return n >= 0 && n <= 7 && state.isStrict(); }); + break; + case "1": + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": + char = "\\" + char; + this.triggerAsync("warning", { + code: "W115", + line: this.line, + character: this.char + }, checks, + function() { return state.isStrict(); }); + break; + case "u": + var sequence = this.input.substr(1, 4); + var code = parseInt(sequence, 16); + if (!isHex(sequence)) { + // This condition unequivocally describes a syntax error. + // TODO: Re-factor as an "error" (not a "warning"). + this.trigger("warning", { + code: "W052", + line: this.line, + character: this.char, + data: [ "u" + sequence ] + }); } - } - } + char = String.fromCharCode(code); + jump = 5; + break; + case "v": + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\v" ] + }, checks, function() { return state.jsonMode; }); - var scopeManagerInst = { + char = "\v"; + break; + case "x": + var x = parseInt(this.input.substr(1, 2), 16); - on: function(names, listener) { - names.split(" ").forEach(function(name) { - emitter.on(name, listener); - }); - }, + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\x-" ] + }, checks, function() { return state.jsonMode; }); - isPredefined: function(labelName) { - return !this.has(labelName) && _.has(_scopeStack[0]["(predefined)"], labelName); - }, + char = String.fromCharCode(x); + jump = 3; + break; + case "\\": + char = "\\\\"; + break; + case "/": + break; + case "": + allowNewLine = true; + char = ""; + break; + } - /** - * Tell the manager we are entering a new block of code - * @param {string} [type] - The type of the block. Valid values are - * "functionparams", "catchparams" and - * "functionouter" - */ - stack: function(type) { - var previousScope = _current; - _newScope(type); + return { char: char, jump: jump, allowNewLine: allowNewLine }; + }, - if (!type && previousScope["(type)"] === "functionparams") { + /* + * Extract a template literal out of the next sequence of characters + * and/or lines or return 'null' if its not possible. Since template + * literals can span across multiple lines, this method has to move + * the char pointer. + */ + scanTemplateLiteral: function(checks) { + var tokenType; + var value = ""; + var ch; + var startLine = this.line; + var startChar = this.char; + var depth = this.templateStarts.length; - _current["(isFuncBody)"] = true; - _current["(context)"] = _currentFunctBody; - _currentFunctBody = _current; + if (this.peek() === "`") { + if (!state.inES6(true)) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: ["template literal syntax", "6"] + }, + checks, + function() { return true; } + ); } - }, - - unstack: function() { - // jshint proto: true - var subScope = _scopeStack.length > 1 ? _scopeStack[_scopeStack.length - 2] : null; - var isUnstackingFunctionBody = _current === _currentFunctBody, - isUnstackingFunctionParams = _current["(type)"] === "functionparams", - isUnstackingFunctionOuter = _current["(type)"] === "functionouter"; - - var i, j; - var currentUsages = _current["(usages)"]; - var currentLabels = _current["(labels)"]; - var usedLabelNameList = Object.keys(currentUsages); + // Template must start with a backtick. + tokenType = Token.TemplateHead; + this.templateStarts.push({ line: this.line, char: this.char }); + depth = this.templateStarts.length; + this.skip(1); + this.pushContext(Context.Template); + } else if (this.inContext(Context.Template) && this.peek() === "}") { + // If we're in a template context, and we have a '}', lex a TemplateMiddle. + tokenType = Token.TemplateMiddle; + } else { + // Go lex something else. + return null; + } - if (currentUsages.__proto__ && usedLabelNameList.indexOf("__proto__") === -1) { - usedLabelNameList.push("__proto__"); + while (this.peek() !== "`") { + while ((ch = this.peek()) === "") { + value += "\n"; + if (!this.nextLine(checks)) { + // Unclosed template literal --- point to the starting "`" + var startPos = this.templateStarts.pop(); + this.trigger("error", { + code: "E052", + line: startPos.line, + character: startPos.char + }); + return { + type: tokenType, + value: value, + startLine: startLine, + startChar: startChar, + isUnclosed: true, + depth: depth, + context: this.popContext() + }; + } } - for (i = 0; i < usedLabelNameList.length; i++) { - var usedLabelName = usedLabelNameList[i]; + if (ch === '$' && this.peek(1) === '{') { + value += '${'; + this.skip(2); + return { + type: tokenType, + value: value, + startLine: startLine, + startChar: startChar, + isUnclosed: false, + depth: depth, + context: this.currentContext() + }; + } else if (ch === '\\') { + var escape = this.scanEscapeSequence(checks); + value += escape.char; + this.skip(escape.jump); + } else if (ch !== '`') { + // Otherwise, append the value and continue. + value += ch; + this.skip(1); + } + } - var usage = currentUsages[usedLabelName]; - var usedLabel = currentLabels[usedLabelName]; - if (usedLabel) { - var usedLabelType = usedLabel["(type)"]; + // Final value is either NoSubstTemplate or TemplateTail + tokenType = tokenType === Token.TemplateHead ? Token.NoSubstTemplate : Token.TemplateTail; + this.skip(1); + this.templateStarts.pop(); - if (usedLabel["(useOutsideOfScope)"] && !state.option.funcscope) { - var usedTokens = usage["(tokens)"]; - if (usedTokens) { - for (j = 0; j < usedTokens.length; j++) { - // Keep the consistency of https://github.com/jshint/jshint/issues/2409 - if (usedLabel["(function)"] === usedTokens[j]["(function)"]) { - error("W038", usedTokens[j], usedLabelName); - } - } - } - } + return { + type: tokenType, + value: value, + startLine: startLine, + startChar: startChar, + isUnclosed: false, + depth: depth, + context: this.popContext() + }; + }, - // mark the label used - _current["(labels)"][usedLabelName]["(unused)"] = false; + /* + * Extract a string out of the next sequence of characters and/or + * lines or return 'null' if its not possible. Since strings can + * span across multiple lines this method has to move the char + * pointer. + * + * This method recognizes pseudo-multiline JavaScript strings: + * + * var str = "hello\ + * world"; + */ + scanStringLiteral: function(checks) { + /*jshint loopfunc:true */ + var quote = this.peek(); - // check for modifying a const - if (usedLabelType === "const" && usage["(modified)"]) { - for (j = 0; j < usage["(modified)"].length; j++) { - error("E013", usage["(modified)"][j], usedLabelName); - } - } + // String must start with a quote. + if (quote !== "\"" && quote !== "'") { + return null; + } - // check for re-assigning a function declaration - if ((usedLabelType === "function" || usedLabelType === "class") && - usage["(reassigned)"]) { - for (j = 0; j < usage["(reassigned)"].length; j++) { - error("W021", usage["(reassigned)"][j], usedLabelName, usedLabelType); - } - } - continue; - } + // In JSON strings must always use double quotes. + this.triggerAsync("warning", { + code: "W108", + line: this.line, + character: this.char // +1? + }, checks, function() { return state.jsonMode && quote !== "\""; }); - if (isUnstackingFunctionOuter) { - state.funct["(isCapturing)"] = true; - } + var value = ""; + var startLine = this.line; + var startChar = this.char; + var allowNewLine = false; - if (subScope) { - // not exiting the global scope, so copy the usage down in case its an out of scope usage - if (!subScope["(usages)"][usedLabelName]) { - subScope["(usages)"][usedLabelName] = usage; - if (isUnstackingFunctionBody) { - subScope["(usages)"][usedLabelName]["(onlyUsedSubFunction)"] = true; - } - } else { - var subScopeUsage = subScope["(usages)"][usedLabelName]; - subScopeUsage["(modified)"] = subScopeUsage["(modified)"].concat(usage["(modified)"]); - subScopeUsage["(tokens)"] = subScopeUsage["(tokens)"].concat(usage["(tokens)"]); - subScopeUsage["(reassigned)"] = - subScopeUsage["(reassigned)"].concat(usage["(reassigned)"]); - subScopeUsage["(onlyUsedSubFunction)"] = false; - } + this.skip(); + + while (this.peek() !== quote) { + if (this.peek() === "") { // End Of Line + + // If an EOL is not preceded by a backslash, show a warning + // and proceed like it was a legit multi-line string where + // author simply forgot to escape the newline symbol. + // + // Another approach is to implicitly close a string on EOL + // but it generates too many false positives. + + if (!allowNewLine) { + // This condition unequivocally describes a syntax error. + // TODO: Emit error E029 and remove W112. + this.trigger("warning", { + code: "W112", + line: this.line, + character: this.char + }); } else { - // this is exiting global scope, so we finalise everything here - we are at the end of the file - if (typeof _current["(predefined)"][usedLabelName] === "boolean") { + allowNewLine = false; - // remove the declared token, so we know it is used - delete declared[usedLabelName]; + // Otherwise show a warning if multistr option was not set. + // For JSON, show warning no matter what. - // note it as used so it can be reported - usedPredefinedAndGlobals[usedLabelName] = marker; + this.triggerAsync("warning", { + code: "W043", + line: this.line, + character: this.char + }, checks, function() { return !state.option.multistr; }); - // check for re-assigning a read-only (set to false) predefined - if (_current["(predefined)"][usedLabelName] === false && usage["(reassigned)"]) { - for (j = 0; j < usage["(reassigned)"].length; j++) { - warning("W020", usage["(reassigned)"][j]); - } - } - } - else { - // label usage is not predefined and we have not found a declaration - // so report as undeclared - if (usage["(tokens)"]) { - for (j = 0; j < usage["(tokens)"].length; j++) { - var undefinedToken = usage["(tokens)"][j]; - // if its not a forgiven undefined (e.g. typof x) - if (!undefinedToken.forgiveUndef) { - // if undef is on and undef was on when the token was defined - if (state.option.undef && !undefinedToken.ignoreUndef) { - warning("W117", undefinedToken, usedLabelName); - } - if (impliedGlobals[usedLabelName]) { - impliedGlobals[usedLabelName].line.push(undefinedToken.line); - } else { - impliedGlobals[usedLabelName] = { - name: usedLabelName, - line: [undefinedToken.line] - }; - } - } - } - } - } + this.triggerAsync("warning", { + code: "W042", + line: this.line, + character: this.char + }, checks, function() { return state.jsonMode && state.option.multistr; }); } - } - // if exiting the global scope, we can warn about declared globals that haven't been used yet - if (!subScope) { - Object.keys(declared) - .forEach(function(labelNotUsed) { - _warnUnused(labelNotUsed, declared[labelNotUsed], "var"); - }); - } + // If we get an EOF inside of an unclosed string, show an + // error and implicitly close it at the EOF point. - // if we have a sub scope we can copy too and we are still within the function boundary - if (subScope && !isUnstackingFunctionBody && - !isUnstackingFunctionParams && !isUnstackingFunctionOuter) { - var labelNames = Object.keys(currentLabels); - for (i = 0; i < labelNames.length; i++) { - - var defLabelName = labelNames[i]; - - // if its function scoped and - // not already defined (caught with shadow, shouldn't also trigger out of scope) - if (!currentLabels[defLabelName]["(blockscoped)"] && - currentLabels[defLabelName]["(type)"] !== "exception" && - !this.funct.has(defLabelName, { excludeCurrent: true })) { - subScope["(labels)"][defLabelName] = currentLabels[defLabelName]; - // we do not warn about out of scope usages in the global scope - if (_currentFunctBody["(type)"] !== "global") { - subScope["(labels)"][defLabelName]["(useOutsideOfScope)"] = true; - } - delete currentLabels[defLabelName]; - } + if (!this.nextLine(checks)) { + return { + type: Token.StringLiteral, + value: value, + startLine: startLine, + startChar: startChar, + isUnclosed: true, + quote: quote + }; } - } - _checkForUnused(); + } else { // Any character other than End Of Line - _scopeStack.pop(); - if (isUnstackingFunctionBody) { - _currentFunctBody = _scopeStack[_.findLastIndex(_scopeStack, function(scope) { - // if function or if global (which is at the bottom so it will only return true if we call back) - return scope["(isFuncBody)"] || scope["(type)"] === "global"; - })]; - } + allowNewLine = false; + var char = this.peek(); + var jump = 1; // A length of a jump, after we're done + // parsing this character. - _current = subScope; - }, + if (char < " ") { + // Warn about a control character in a string. + this.triggerAsync( + "warning", + { + code: "W113", + line: this.line, + character: this.char, + data: [ "" ] + }, + checks, + function() { return true; } + ); + } - /** - * Add a param to the current scope - * @param {string} labelName - * @param {Token} token - * @param {string} [type="param"] param type - */ - addParam: function(labelName, token, type) { - type = type || "param"; + // Special treatment for some escaped characters. + if (char === "\\") { + var parsed = this.scanEscapeSequence(checks); + char = parsed.char; + jump = parsed.jump; + allowNewLine = parsed.allowNewLine; + } - if (type === "exception") { - // if defined in the current function - var previouslyDefinedLabelType = this.funct.labeltype(labelName); - if (previouslyDefinedLabelType && previouslyDefinedLabelType !== "exception") { - // and has not been used yet in the current function scope - if (!state.option.node) { - warning("W002", state.tokens.next, labelName); - } + // If char is the empty string, end of the line has been reached. In + // this case, `this.char` should not be incremented so that warnings + // and errors reported in the subsequent loop iteration have the + // correct character column offset. + if (char !== "") { + value += char; + this.skip(jump); } } + } - // The variable was declared in the current scope - if (_.has(_current["(labels)"], labelName)) { - _current["(labels)"][labelName].duplicated = true; - - // The variable was declared in an outer scope - } else { - // if this scope has the variable defined, it's a re-definition error - _checkOuterShadow(labelName, token, type); + this.skip(); + return { + type: Token.StringLiteral, + value: value, + startLine: startLine, + startChar: startChar, + isUnclosed: false, + quote: quote + }; + }, - _current["(labels)"][labelName] = { - "(type)" : type, - "(token)": token, - "(unused)": true }; + /* + * Extract a regular expression out of the next sequence of + * characters and/or lines or return 'null' if its not possible. + * + * This method is platform dependent: it accepts almost any + * regular expression values but then tries to compile and run + * them using system's RegExp object. This means that there are + * rare edge cases where one JavaScript engine complains about + * your regular expression while others don't. + */ + scanRegExp: function(checks) { + var index = 0; + var length = this.input.length; + var char = this.peek(); + var value = char; + var body = ""; + var groupReferences = []; + var allFlags = ""; + var es5Flags = ""; + var malformed = false; + var isCharSet = false; + var isCharSetRange = false; + var isGroup = false; + var isQuantifiable = false; + var hasInvalidQuantifier = false; + var escapedChars = ""; + var hasUFlag = function() { return allFlags.indexOf("u") > -1; }; + var escapeSequence; + var groupCount = 0; + var terminated, malformedDesc; + + var scanRegexpEscapeSequence = function() { + var next, sequence; + index += 1; + char = this.peek(index); - _current["(params)"].push(labelName); + if (reg.nonzeroDigit.test(char)) { + sequence = char; + next = this.peek(index + 1); + while (reg.nonzeroDigit.test(next) || next === "0") { + index += 1; + char = next; + sequence += char; + body += char; + value += char; + next = this.peek(index + 1); + } + groupReferences.push(Number(sequence)); + return sequence; } - if (_.has(_current["(usages)"], labelName)) { - var usage = _current["(usages)"][labelName]; - // if its in a sub function it is not necessarily an error, just latedef - if (usage["(onlyUsedSubFunction)"]) { - _latedefWarning(type, labelName, token); - } else { - // this is a clear illegal usage for block scoped variables - warning("E056", token, labelName, type); + escapedChars += char; + + if (char === "u" && this.peek(index + 1) === "{") { + var x = index + 2; + sequence = "u{"; + next = this.peek(x); + while (isHex(next)) { + sequence += next; + x += 1; + next = this.peek(x); } - } - }, - validateParams: function() { - // This method only concerns errors for function parameters - if (_currentFunctBody["(type)"] === "global") { - return; + if (next !== "}") { + this.triggerAsync( + "error", + { + code: "E016", + line: this.line, + character: this.char, + data: [ "Invalid Unicode escape sequence" ] + }, + checks, + hasUFlag + ); + } else if (sequence.length > 2) { + sequence += "}"; + body += sequence; + value += sequence; + index = x + 1; + return sequence; + } } - var isStrict = state.isStrict(); - var currentFunctParamScope = _currentFunctBody["(parent)"]; + if (char === "p" || char === "P") { + var y = index + 2; + sequence = ""; + next = ""; - if (!currentFunctParamScope["(params)"]) { - return; - } + if (this.peek(index + 1) === "{") { + next = this.peek(y); + while (next && next !== "}") { + sequence += next; + y += 1; + next = this.peek(y); + } + } - currentFunctParamScope["(params)"].forEach(function(labelName) { - var label = currentFunctParamScope["(labels)"][labelName]; + // Module loading is intentionally deferred as an optimization for + // Node.js users who do not use Unicode escape sequences. + if (!sequence || !_dereq_("./validate-unicode-escape-sequence")(sequence)) { + this.triggerAsync( + "error", + { + code: "E016", + line: this.line, + character: this.char, + data: [ "Invalid Unicode property escape sequence" ] + }, + checks, + hasUFlag + ); + } - if (label && label.duplicated) { - if (isStrict) { - warning("E011", label["(token)"], labelName); - } else if (state.option.shadow !== true) { - warning("W004", label["(token)"], labelName); + if (sequence) { + sequence = char + "{" + sequence + "}"; + body += sequence; + value += sequence; + index = y + 1; + + if (!state.inES9()) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: [ "Unicode property escape", "9" ] + }, + checks, + hasUFlag + ); } + + return sequence; } - }); - }, + } - getUsedOrDefinedGlobals: function() { - // jshint proto: true - var list = Object.keys(usedPredefinedAndGlobals); + // Unexpected control character + if (char < " ") { + malformed = true; + this.triggerAsync( + "warning", + { + code: "W048", + line: this.line, + character: this.char + }, + checks, + function() { return true; } + ); + } - // If `__proto__` is used as a global variable name, its entry in the - // lookup table may not be enumerated by `Object.keys` (depending on the - // environment). - if (usedPredefinedAndGlobals.__proto__ === marker && - list.indexOf("__proto__") === -1) { - list.push("__proto__"); + // Unexpected escaped character + if (char === "<") { + malformed = true; + this.triggerAsync( + "warning", + { + code: "W049", + line: this.line, + character: this.char, + data: [ char ] + }, + checks, + function() { return true; } + ); + } else if (char === "0" && reg.decimalDigit.test(this.peek(index + 1))) { + this.triggerAsync( + "error", + { + code: "E016", + line: this.line, + character: this.char, + data: [ "Invalid decimal escape sequence" ] + }, + checks, + hasUFlag + ); } - return list; - }, + index += 1; + body += char; + value += char; - /** - * Gets an array of implied globals - * @returns {Array.<{ name: string, line: Array.}>} - */ - getImpliedGlobals: function() { - // jshint proto: true - var values = _.values(impliedGlobals); - var hasProto = false; + return char; + }.bind(this); - // If `__proto__` is an implied global variable, its entry in the lookup - // table may not be enumerated by `_.values` (depending on the - // environment). - if (impliedGlobals.__proto__) { - hasProto = values.some(function(value) { - return value.name === "__proto__"; - }); + var checkQuantifier = function() { + var lookahead = index; + var lowerBound = ""; + var upperBound = ""; + var next; - if (!hasProto) { - values.push(impliedGlobals.__proto__); - } + next = this.peek(lookahead + 1); + + while (reg.decimalDigit.test(next)) { + lookahead += 1; + lowerBound += next; + next = this.peek(lookahead + 1); } - return values; - }, + if (!lowerBound) { + return false; + } - /** - * Returns a list of unused variables - * @returns {Array} - */ - getUnuseds: function() { - return unuseds; - }, + if (next === "}") { + return true; + } - has: function(labelName) { - return Boolean(_getLabel(labelName)); - }, + if (next !== ",") { + return false; + } + + lookahead += 1; + next = this.peek(lookahead + 1); - labeltype: function(labelName) { - // returns a labels type or null if not present - var scopeLabels = _getLabel(labelName); - if (scopeLabels) { - return scopeLabels[labelName]["(type)"]; + while (reg.decimalDigit.test(next)) { + lookahead += 1; + upperBound += next; + next = this.peek(lookahead + 1); } - return null; - }, - /** - * for the exported options, indicating a variable is used outside the file - */ - addExported: function(labelName) { - var globalLabels = _scopeStack[0]["(labels)"]; - if (_.has(declared, labelName)) { - // remove the declared token, so we know it is used - delete declared[labelName]; - } else if (_.has(globalLabels, labelName)) { - globalLabels[labelName]["(unused)"] = false; - } else { - for (var i = 1; i < _scopeStack.length; i++) { - var scope = _scopeStack[i]; - // if `scope.(type)` is not defined, it is a block scope - if (!scope["(type)"]) { - if (_.has(scope["(labels)"], labelName) && - !scope["(labels)"][labelName]["(blockscoped)"]) { - scope["(labels)"][labelName]["(unused)"] = false; - return; - } - } else { - break; - } - } - exported[labelName] = true; + if (next !== "}") { + return false; } - }, - - /** - * Mark an indentifier as es6 module exported - */ - setExported: function(labelName, token) { - this.block.use(labelName, token); - }, - - /** - * adds an indentifier to the relevant current scope and creates warnings/errors as necessary - * @param {string} labelName - * @param {Object} opts - * @param {String} opts.type - the type of the label e.g. "param", "var", "let, "const", "function" - * @param {Token} opts.token - the token pointing at the declaration - */ - addlabel: function(labelName, opts) { - - var type = opts.type; - var token = opts.token; - var isblockscoped = type === "let" || type === "const" || type === "class"; - var isexported = (isblockscoped ? _current : _currentFunctBody)["(type)"] === "global" && - _.has(exported, labelName); - // outer shadow check (inner is only on non-block scoped) - _checkOuterShadow(labelName, token, type); + if (upperBound) { + return Number(lowerBound) <= Number(upperBound); + } - // if is block scoped (let or const) - if (isblockscoped) { + return true; + }.bind(this); - var declaredInCurrentScope = _current["(labels)"][labelName]; - // for block scoped variables, params are seen in the current scope as the root function - // scope, so check these too. - if (!declaredInCurrentScope && _current === _currentFunctBody && - _current["(type)"] !== "global") { - declaredInCurrentScope = !!_currentFunctBody["(parent)"]["(labels)"][labelName]; - } + var translateUFlag = function(body) { + // The BMP character to use as a replacement for astral symbols when + // translating an ES6 "u"-flagged pattern to an ES5-compatible + // approximation. + // Note: replacing with '\uFFFF' enables false positives in unlikely + // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid pattern + // that would not be detected by this substitution. + var astralSubstitute = "\uFFFF"; + + return body + // Replace every Unicode escape sequence with the equivalent BMP + // character or a constant ASCII code point in the case of astral + // symbols. (See the above note on `astralSubstitute` for more + // information.) + .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function($0, $1, $2) { + var codePoint = parseInt($1 || $2, 16); + var literal; + + if (codePoint > 0x10FFFF) { + malformed = true; + this.trigger("error", { + code: "E016", + line: this.line, + character: this.char, + data: [ char ] + }); - // if its not already defined (which is an error, so ignore) and is used in TDZ - if (!declaredInCurrentScope && _current["(usages)"][labelName]) { - var usage = _current["(usages)"][labelName]; - // if its in a sub function it is not necessarily an error, just latedef - if (usage["(onlyUsedSubFunction)"]) { - _latedefWarning(type, labelName, token); - } else { - // this is a clear illegal usage for block scoped variables - warning("E056", token, labelName, type); + return; } - } - - // if this scope has the variable defined, its a re-definition error - if (declaredInCurrentScope) { - warning("E011", token, labelName); - } - else if (state.option.shadow === "outer") { + literal = String.fromCharCode(codePoint); - // if shadow is outer, for block scope we want to detect any shadowing within this function - if (scopeManagerInst.funct.has(labelName)) { - warning("W004", token, labelName); + if (reg.regexpSyntaxChars.test(literal)) { + return $0; } - } - scopeManagerInst.block.add(labelName, type, token, !isexported); + if (codePoint <= 0xFFFF) { + return String.fromCharCode(codePoint); + } + return astralSubstitute; + }.bind(this)) + // Replace each paired surrogate with a single ASCII symbol to avoid + // throwing on regular expressions that are only valid in combination + // with the "u" flag. + .replace( + /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + astralSubstitute + ); + }.bind(this); - } else { + // Regular expressions must start with '/' + if (!this.prereg || char !== "/") { + return null; + } - var declaredInCurrentFunctionScope = scopeManagerInst.funct.has(labelName); + index += 1; + terminated = false; - // check for late definition, ignore if already declared - if (!declaredInCurrentFunctionScope && usedSoFarInCurrentFunction(labelName)) { - _latedefWarning(type, labelName, token); - } + // Try to get everything in between slashes. A couple of + // cases aside (see scanRegexpEscapeSequence) we don't really + // care whether the resulting expression is valid or not. + // We will check that later using the RegExp object. - // defining with a var or a function when a block scope variable of the same name - // is in scope is an error - if (scopeManagerInst.funct.has(labelName, { onlyBlockscoped: true })) { - warning("E011", token, labelName); - } else if (state.option.shadow !== true) { - // now since we didn't get any block scope variables, test for var/function - // shadowing - if (declaredInCurrentFunctionScope && labelName !== "__proto__") { + while (index < length) { + // Because an iteration of this loop may terminate in a number of + // distinct locations, `isCharSetRange` is re-set at the onset of + // iteration. + isCharSetRange &= char === "-"; + char = this.peek(index); + value += char; + body += char; - // see https://github.com/jshint/jshint/issues/2400 - if (_currentFunctBody["(type)"] !== "global") { - warning("W004", token, labelName); - } + if (isCharSet) { + if (char === "]") { + if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") { + isCharSet = false; } - } - - scopeManagerInst.funct.add(labelName, type, token, !isexported); - - if (_currentFunctBody["(type)"] === "global") { - usedPredefinedAndGlobals[labelName] = marker; + } else if (char === "-") { + isCharSetRange = true; } } - }, - - funct: { - /** - * Returns the label type given certain options - * @param labelName - * @param {Object=} options - * @param {Boolean=} options.onlyBlockscoped - only include block scoped labels - * @param {Boolean=} options.excludeParams - exclude the param scope - * @param {Boolean=} options.excludeCurrent - exclude the current scope - * @returns {String} - */ - labeltype: function(labelName, options) { - var onlyBlockscoped = options && options.onlyBlockscoped; - var excludeParams = options && options.excludeParams; - var currentScopeIndex = _scopeStack.length - (options && options.excludeCurrent ? 2 : 1); - for (var i = currentScopeIndex; i >= 0; i--) { - var current = _scopeStack[i]; - if (current["(labels)"][labelName] && - (!onlyBlockscoped || current["(labels)"][labelName]["(blockscoped)"])) { - return current["(labels)"][labelName]["(type)"]; - } - var scopeCheck = excludeParams ? _scopeStack[ i - 1 ] : current; - if (scopeCheck && scopeCheck["(type)"] === "functionparams") { - return null; - } - } - return null; - }, - /** - * Returns if a break label exists in the function scope - * @param {string} labelName - * @returns {boolean} - */ - hasBreakLabel: function(labelName) { - for (var i = _scopeStack.length - 1; i >= 0; i--) { - var current = _scopeStack[i]; - if (current["(breakLabels)"][labelName]) { - return true; - } - if (current["(type)"] === "functionparams") { - return false; - } + if (char === "\\") { + escapeSequence = scanRegexpEscapeSequence(); + + if (isCharSet && (this.peek(index) === "-" || isCharSetRange) && + reg.regexpCharClasses.test(escapeSequence)) { + this.triggerAsync( + "error", + { + code: "E016", + line: this.line, + character: this.char, + data: [ "Character class used in range" ] + }, + checks, + hasUFlag + ); } - return false; - }, - /** - * Returns if the label is in the current function scope - * See scopeManager.funct.labelType for options - */ - has: function(labelName, options) { - return Boolean(this.labeltype(labelName, options)); - }, - /** - * Adds a new function scoped variable - * see block.add for block scoped - */ - add: function(labelName, type, tok, unused) { - _current["(labels)"][labelName] = { - "(type)" : type, - "(token)": tok, - "(blockscoped)": false, - "(function)": _currentFunctBody, - "(unused)": unused }; + continue; } - }, - - block: { - /** - * is the current block global? - * @returns Boolean - */ - isGlobal: function() { - return _current["(type)"] === "global"; - }, + if (isCharSet) { + index += 1; + continue; + } - use: function(labelName, token) { + if (char === "{" && !hasInvalidQuantifier) { + hasInvalidQuantifier = !checkQuantifier(); + } - // if resolves to current function params, then do not store usage just resolve - // this is because function(a) { var a; a = a; } will resolve to the param, not - // to the unset var - // first check the param is used - var paramScope = _currentFunctBody["(parent)"]; - if (paramScope && paramScope["(labels)"][labelName] && - paramScope["(labels)"][labelName]["(type)"] === "param") { + if (char === "[") { + isCharSet = true; + index += 1; + continue; + } else if (char === "(") { + isGroup = true; - // then check its not declared by a block scope variable - if (!scopeManagerInst.funct.has(labelName, - { excludeParams: true, onlyBlockscoped: true })) { - paramScope["(labels)"][labelName]["(unused)"] = false; + if (this.peek(index + 1) === "?" && + (this.peek(index + 2) === "=" || this.peek(index + 2) === "!")) { + isQuantifiable = true; + } + } else if (char === ")") { + if (isQuantifiable) { + isQuantifiable = false; + + if (reg.regexpQuantifiers.test(this.peek(index + 1))) { + this.triggerAsync( + "error", + { + code: "E016", + line: this.line, + character: this.char, + data: [ "Quantified quantifiable" ] + }, + checks, + hasUFlag + ); } + } else { + groupCount += 1; } - if (token && (state.ignored.W117 || state.option.undef === false)) { - token.ignoreUndef = true; - } + isGroup = false; + } else if (char === "/") { + body = body.substr(0, body.length - 1); + terminated = true; + index += 1; + break; + } - _setupUsages(labelName); + index += 1; + } - if (token) { - token["(function)"] = _currentFunctBody; - _current["(usages)"][labelName]["(tokens)"].push(token); - } - }, + // A regular expression that was never closed is an + // error from which we cannot recover. + + if (!terminated) { + this.trigger("error", { + code: "E015", + line: this.line, + character: this.from + }); - reassign: function(labelName, token) { + return void this.trigger("fatal", { + line: this.line, + from: this.from + }); + } - this.modify(labelName, token); + // Parse flags (if any). - _current["(usages)"][labelName]["(reassigned)"].push(token); - }, + while (index < length) { + char = this.peek(index); + if (!/[gimyus]/.test(char)) { + break; + } + if (char === "y") { + if (!state.inES6(true)) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: [ "Sticky RegExp flag", "6" ] + }, + checks, + function() { return true; } + ); + } + } else if (char === "u") { + if (!state.inES6(true)) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: [ "Unicode RegExp flag", "6" ] + }, + checks, + function() { return true; } + ); + } - modify: function(labelName, token) { + var hasInvalidEscape = (function(groupReferences, groupCount, escapedChars, reg) { + var hasInvalidGroup = groupReferences.some(function(groupReference) { + if (groupReference > groupCount) { + return true; + } + }); - _setupUsages(labelName); + if (hasInvalidGroup) { + return true; + } - _current["(usages)"][labelName]["(modified)"].push(token); - }, + return !escapedChars.split("").every(function(escapedChar) { + return escapedChar === "u" || + escapedChar === "/" || + escapedChar === "0" || + reg.regexpControlEscapes.test(escapedChar) || + reg.regexpCharClasses.test(escapedChar) || + reg.regexpSyntaxChars.test(escapedChar); + }); + }(groupReferences, groupCount, escapedChars, reg)); - /** - * Adds a new variable - */ - add: function(labelName, type, tok, unused) { - _current["(labels)"][labelName] = { - "(type)" : type, - "(token)": tok, - "(blockscoped)": true, - "(unused)": unused }; - }, + if (hasInvalidEscape) { + malformedDesc = "Invalid escape"; + } else if (hasInvalidQuantifier) { + malformedDesc = "Invalid quantifier"; + } - addBreakLabel: function(labelName, opts) { - var token = opts.token; - if (scopeManagerInst.funct.hasBreakLabel(labelName)) { - warning("E011", token, labelName); + body = translateUFlag(body); + } else if (char === "s") { + if (!state.inES9()) { + this.triggerAsync( + "warning", + { + code: "W119", + line: this.line, + character: this.char, + data: [ "DotAll RegExp flag", "9" ] + }, + checks, + function() { return true; } + ); } - else if (state.option.shadow === "outer") { - if (scopeManagerInst.funct.has(labelName)) { - warning("W004", token, labelName); - } else { - _checkOuterShadow(labelName, token); - } + if (value.indexOf("s") > -1) { + malformedDesc = "Duplicate RegExp flag"; } - _current["(breakLabels)"][labelName] = token; + } else { + es5Flags += char; } - } - }; - return scopeManagerInst; -}; -module.exports = scopeManager; + if (allFlags.indexOf(char) > -1) { + malformedDesc = "Duplicate RegExp flag"; + } + allFlags += char; -},{"../lodash":"/node_modules/jshint/lodash.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/state.js":[function(_dereq_,module,exports){ -"use strict"; -var NameStack = _dereq_("./name-stack.js"); + value += char; + allFlags += char; + index += 1; + } -var state = { - syntax: {}, + if (allFlags.indexOf("u") === -1) { + this.triggerAsync("warning", { + code: "W147", + line: this.line, + character: this.char + }, checks, function() { return state.option.regexpu; }); + } - /** - * Determine if the code currently being linted is strict mode code. - * - * @returns {boolean} - */ - isStrict: function() { - return this.directive["use strict"] || this.inClassBody || - this.option.module || this.option.strict === "implied"; - }, + // Check regular expression for correctness. - // Assumption: chronologically ES3 < ES5 < ES6 < Moz + try { + new RegExp(body, es5Flags); + } catch (err) { + /** + * Because JSHint relies on the current engine's RegExp parser to + * validate RegExp literals, the description (exposed as the "data" + * property on the error object) is platform dependent. + */ + malformedDesc = err.message; + } - inMoz: function() { - return this.option.moz; + if (malformedDesc) { + malformed = true; + this.trigger("error", { + code: "E016", + line: this.line, + character: this.char, + data: [ malformedDesc ] + }); + } else if (allFlags.indexOf("s") > -1 && !reg.regexpDot.test(body)) { + this.trigger("warning", { + code: "W148", + line: this.line, + character: this.char + }); + } + + return { + type: Token.RegExp, + value: value, + isMalformed: malformed + }; }, - /** - * @param {boolean} strict - When `true`, only consider ES6 when in - * "esversion: 6" code and *not* in "moz". + /* + * Scan for any occurrence of non-breaking spaces. Non-breaking spaces + * can be mistakenly typed on OS X with option-space. Non UTF-8 web + * pages with non-breaking pages produce syntax errors. */ - inES6: function() { - return this.option.moz || this.option.esversion >= 6; + scanNonBreakingSpaces: function() { + return state.option.nonbsp ? + this.input.search(/(\u00A0)/) : -1; }, - /** - * @param {boolean} strict - When `true`, return `true` only when - * esversion is exactly 5 + /* + * Produce the next raw token or return 'null' if no tokens can be matched. + * This method skips over all space characters. */ - inES5: function(strict) { - if (strict) { - return (!this.option.esversion || this.option.esversion === 5) && !this.option.moz; - } - return !this.option.esversion || this.option.esversion >= 5 || this.option.moz; - }, + next: function(checks) { + this.from = this.char; + // Move to the next non-space character. + while (reg.whitespace.test(this.peek())) { + this.from += 1; + this.skip(); + } - reset: function() { - this.tokens = { - prev: null, - next: null, - curr: null - }; + // Methods that work with multi-line structures and move the + // character pointer. - this.option = {}; - this.funct = null; - this.ignored = {}; - this.directive = {}; - this.jsonMode = false; - this.jsonWarnings = []; - this.lines = []; - this.tab = ""; - this.cache = {}; // Node.JS doesn't have Map. Sniff. - this.ignoredLines = {}; - this.forinifcheckneeded = false; - this.nameStack = new NameStack(); - this.inClassBody = false; - } -}; + var match = this.scanComments(checks) || + this.scanStringLiteral(checks) || + this.scanTemplateLiteral(checks); -exports.state = state; + if (match) { + return match; + } -},{"./name-stack.js":"/node_modules/jshint/src/name-stack.js"}],"/node_modules/jshint/src/style.js":[function(_dereq_,module,exports){ -"use strict"; + // Methods that don't move the character pointer. -exports.register = function(linter) { - // Check for properties named __proto__. This special property was - // deprecated and then re-introduced for ES6. + match = + this.scanRegExp(checks) || + this.scanPunctuator() || + this.scanKeyword() || + this.scanIdentifier(checks) || + this.scanNumericLiteral(checks); - linter.on("Identifier", function style_scanProto(data) { - if (linter.getOption("proto")) { - return; + if (match) { + this.skip(match.tokenLength || match.value.length); + return match; } - if (data.name === "__proto__") { - linter.warn("W103", { - line: data.line, - char: data.char, - data: [ data.name, "6" ] - }); - } - }); + // No token could be matched, give up. - // Check for properties named __iterator__. This is a special property - // available only in browsers with JavaScript 1.7 implementation, but - // it is deprecated for ES6 + return null; + }, - linter.on("Identifier", function style_scanIterator(data) { - if (linter.getOption("iterator")) { - return; - } + /* + * Switch to the next line and reset all char pointers. Once + * switched, this method also checks for other minor warnings. + */ + nextLine: function(checks) { + var char; - if (data.name === "__iterator__") { - linter.warn("W103", { - line: data.line, - char: data.char, - data: [ data.name ] - }); + if (this.line >= this.getLines().length) { + return false; } - }); - // Check that all identifiers are using camelCase notation. - // Exceptions: names like MY_VAR and _myVar. + this.input = this.getLines()[this.line]; + this.line += 1; + this.char = 1; + this.from = 1; - linter.on("Identifier", function style_scanCamelCase(data) { - if (!linter.getOption("camelcase")) { - return; - } + var inputTrimmed = this.input.trim(); - if (data.name.replace(/^_+|_+$/g, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) { - linter.warn("W106", { - line: data.line, - char: data.from, - data: [ data.name ] + var startsWith = function() { + return _.some(arguments, function(prefix) { + return inputTrimmed.indexOf(prefix) === 0; }); - } - }); - - // Enforce consistency in style of quoting. + }; - linter.on("String", function style_scanQuotes(data) { - var quotmark = linter.getOption("quotmark"); - var code; + var endsWith = function() { + return _.some(arguments, function(suffix) { + return inputTrimmed.indexOf(suffix, inputTrimmed.length - suffix.length) !== -1; + }); + }; - if (!quotmark) { - return; + // If we are ignoring linter errors, replace the input with empty string + // if it doesn't already at least start or end a multi-line comment + if (this.ignoringLinterErrors === true) { + if (!startsWith("/*", "//") && !(this.inComment && endsWith("*/"))) { + this.input = ""; + } } - // If quotmark is set to 'single' warn about all double-quotes. - - if (quotmark === "single" && data.quote !== "'") { - code = "W109"; + char = this.scanNonBreakingSpaces(); + if (char >= 0) { + this.triggerAsync( + "warning", + { code: "W125", line: this.line, character: char + 1 }, + checks, + function() { return true; } + ); } - // If quotmark is set to 'double' warn about all single-quotes. + this.input = this.input.replace(/\t/g, state.tab); - if (quotmark === "double" && data.quote !== "\"") { - code = "W108"; - } + // If there is a limit on line length, warn when lines get too + // long. - // If quotmark is set to true, remember the first quotation style - // and then warn about all others. + if (!this.ignoringLinterErrors && state.option.maxlen && + state.option.maxlen < this.input.length) { + var inComment = this.inComment || + startsWith.call(inputTrimmed, "//") || + startsWith.call(inputTrimmed, "/*"); - if (quotmark === true) { - if (!linter.getCache("quotmark")) { - linter.setCache("quotmark", data.quote); - } + var shouldTriggerError = !inComment || !reg.maxlenException.test(inputTrimmed); - if (linter.getCache("quotmark") !== data.quote) { - code = "W110"; + if (shouldTriggerError) { + this.triggerAsync( + "warning", + { code: "W101", line: this.line, character: this.input.length }, + checks, + function() { return true; } + ); } } - if (code) { - linter.warn(code, { - line: data.line, - char: data.char, - }); - } - }); + return true; + }, - linter.on("Number", function style_scanNumbers(data) { - if (data.value.charAt(0) === ".") { - // Warn about a leading decimal point. - linter.warn("W008", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } + /* + * Produce the next token. This function is called by advance() to get + * the next token. It returns a token in a JSLint-compatible format. + */ + token: function() { + /*jshint loopfunc:true */ + var checks = asyncTrigger(); + var token; - if (data.value.substr(data.value.length - 1) === ".") { - // Warn about a trailing decimal point. - linter.warn("W047", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } + // Produce a token object. + var create = function(type, value, isProperty, token) { + /*jshint validthis:true */ + var obj; - if (/^00+/.test(data.value)) { - // Multiple leading zeroes. - linter.warn("W046", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } - }); + if (type !== "(endline)" && type !== "(end)") { + this.prereg = false; + } - // Warn about script URLs. + if (type === "(punctuator)") { + switch (value) { + case ".": + case ")": + case "~": + case "#": + case "]": + case "}": + case "++": + case "--": + this.prereg = false; + break; + default: + this.prereg = true; + } - linter.on("String", function style_scanJavaScriptURLs(data) { - var re = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i; + obj = Object.create(state.syntax[value] || state.syntax["(error)"]); + } - if (linter.getOption("scripturl")) { - return; - } + if (type === "(identifier)") { + if (value === "return" || value === "case" || value === "yield" || + value === "typeof" || value === "instanceof" || value === "void" || + value === "await" || value === "new" || value === "delete" || + value === "default" || value === "extends") { + this.prereg = true; + } - if (re.test(data.value)) { - linter.warn("W107", { - line: data.line, - char: data.char - }); - } - }); -}; + if (_.has(state.syntax, value)) { + obj = Object.create(state.syntax[value] || state.syntax["(error)"]); + } + } -},{}],"/node_modules/jshint/src/vars.js":[function(_dereq_,module,exports){ -// jshint -W001 + if (type === "(template)" || type === "(template middle)") { + this.prereg = true; + } -"use strict"; + if (!obj) { + obj = Object.create(state.syntax[type]); + } -// Identifiers provided by the ECMAScript standard. + obj.identifier = (type === "(identifier)"); + obj.type = obj.type || type; + obj.value = value; + obj.line = this.line; + obj.character = this.char; + obj.from = this.from; + if (obj.identifier && token) obj.raw_text = token.text || token.value; + if (token && token.startLine && token.startLine !== this.line) { + obj.startLine = token.startLine; + } + if (token && token.context) { + // Context of current token + obj.context = token.context; + } + if (token && token.depth) { + // Nested template depth + obj.depth = token.depth; + } + if (token && token.isUnclosed) { + // Mark token as unclosed string / template literal + obj.isUnclosed = token.isUnclosed; + } -exports.reservedVars = { - arguments : false, - NaN : false -}; + if (isProperty && obj.identifier) { + obj.isProperty = isProperty; + } -exports.ecmaIdentifiers = { - 3: { - Array : false, - Boolean : false, - Date : false, - decodeURI : false, - decodeURIComponent : false, - encodeURI : false, - encodeURIComponent : false, - Error : false, - "eval" : false, - EvalError : false, - Function : false, - hasOwnProperty : false, - isFinite : false, - isNaN : false, - Math : false, - Number : false, - Object : false, - parseInt : false, - parseFloat : false, - RangeError : false, - ReferenceError : false, - RegExp : false, - String : false, - SyntaxError : false, - TypeError : false, - URIError : false - }, - 5: { - JSON : false - }, - 6: { - Map : false, - Promise : false, - Proxy : false, - Reflect : false, - Set : false, - Symbol : false, - WeakMap : false, - WeakSet : false + obj.check = checks.check; + + return obj; + }.bind(this); + + for (;;) { + if (!this.input.length) { + if (this.nextLine(checks)) { + return create("(endline)", ""); + } + + if (this.exhausted) { + return null; + } + + this.exhausted = true; + return create("(end)", ""); + } + + token = this.next(checks); + + if (!token) { + if (this.input.length) { + // Unexpected character. + this.trigger("error", { + code: "E024", + line: this.line, + character: this.char, + data: [ this.peek() ] + }); + + this.input = ""; + } + + continue; + } + + switch (token.type) { + case Token.StringLiteral: + this.triggerAsync("String", { + line: this.line, + char: this.char, + from: this.from, + startLine: token.startLine, + startChar: token.startChar, + value: token.value, + quote: token.quote + }, checks, function() { return true; }); + + return create("(string)", token.value, null, token); + + case Token.TemplateHead: + this.trigger("TemplateHead", { + line: this.line, + char: this.char, + from: this.from, + startLine: token.startLine, + startChar: token.startChar, + value: token.value + }); + return create("(template)", token.value, null, token); + + case Token.TemplateMiddle: + this.trigger("TemplateMiddle", { + line: this.line, + char: this.char, + from: this.from, + startLine: token.startLine, + startChar: token.startChar, + value: token.value + }); + return create("(template middle)", token.value, null, token); + + case Token.TemplateTail: + this.trigger("TemplateTail", { + line: this.line, + char: this.char, + from: this.from, + startLine: token.startLine, + startChar: token.startChar, + value: token.value + }); + return create("(template tail)", token.value, null, token); + + case Token.NoSubstTemplate: + this.trigger("NoSubstTemplate", { + line: this.line, + char: this.char, + from: this.from, + startLine: token.startLine, + startChar: token.startChar, + value: token.value + }); + return create("(no subst template)", token.value, null, token); + + case Token.Identifier: + this.triggerAsync("Identifier", { + line: this.line, + char: this.char, + from: this.from, + name: token.value, + raw_name: token.text, + isProperty: state.tokens.curr.id === "." + }, checks, function() { return true; }); + + /* falls through */ + case Token.Keyword: + return create("(identifier)", token.value, state.tokens.curr.id === ".", token); + + case Token.NumericLiteral: + if (token.isMalformed) { + this.trigger("error", { + code: "E067", + line: this.line, + character: this.char, + data: [ token.value ] + }); + } + + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "0x-" ] + }, checks, function() { return token.base === 16 && state.jsonMode; }); + + this.triggerAsync("warning", { + code: "W115", + line: this.line, + character: this.char + }, checks, function() { + return state.isStrict() && token.base === 8 && token.isLegacy; + }); + + this.triggerAsync("error", { + code: "E068", + line: this.line, + character: this.char + }, checks, function() { + return state.isStrict() && token.isNonOctal; + }); + + this.trigger("Number", { + line: this.line, + char: this.char, + from: this.from, + value: token.value, + base: token.base, + isMalformed: token.isMalformed + }); + + return create("(number)", token.value); + + case Token.RegExp: + return create("(regexp)", token.value); + + case Token.Comment: + if (token.isSpecial) { + return { + id: '(comment)', + value: token.value, + body: token.body, + type: token.commentType, + isSpecial: token.isSpecial, + line: this.line, + character: this.char, + from: this.from + }; + } + + break; + + default: + return create("(punctuator)", token.value); + } + } } }; -// Global variables commonly provided by a web browser environment. +exports.Lexer = Lexer; +exports.Context = Context; -exports.browser = { - Audio : false, +},{"../data/ascii-identifier-data.js":"/../../../jshint/data/ascii-identifier-data.js","../data/es5-identifier-names.js":"/../../../jshint/data/es5-identifier-names.js","../data/non-ascii-identifier-part-only.js":"/../../../jshint/data/non-ascii-identifier-part-only.js","../data/non-ascii-identifier-start.js":"/../../../jshint/data/non-ascii-identifier-start.js","./reg.js":"/../../../jshint/src/reg.js","./state.js":"/../../../jshint/src/state.js","./validate-unicode-escape-sequence":"/../../../jshint/src/validate-unicode-escape-sequence.js","events":"/node_modules/events/events.js","underscore":"/../../../jshint/node_modules/underscore/underscore-umd.js"}],"/../../../jshint/src/messages.js":[function(_dereq_,module,exports){ +"use strict"; + +var _ = _dereq_("underscore"); + +var errors = { + // JSHint options + E001: "Bad {a}option: '{b}'.", + E002: "Bad option value.", + + // JSHint input + E003: "Expected a JSON value.", + E004: "Input is neither a string nor an array of strings.", + E005: "Input is empty.", + E006: "Unexpected early end of program.", + + // Strict mode + E007: "Missing \"use strict\" statement.", + E008: "Strict violation.", + E009: "Option 'validthis' can't be used in a global scope.", + E010: "'with' is not allowed in strict mode.", + + // Constants + E011: "'{a}' has already been declared.", + E012: "Missing initializer for constant '{a}'.", + E013: "Attempting to override '{a}' which is a constant.", + + // Regular expressions + E014: "A regular expression literal can be confused with '/='.", + E015: "Unclosed regular expression.", + E016: "Invalid regular expression.", + + // Tokens + E017: "Unclosed comment.", + E018: "Unbegun comment.", + E019: "Unmatched '{a}'.", + E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", + E021: "Expected '{a}' and instead saw '{b}'.", + E022: "Line breaking error '{a}'.", + E023: "Missing '{a}'.", + E024: "Unexpected '{a}'.", + E025: "Missing ':' on a case clause.", + E026: "Missing '}' to match '{' from line {a}.", + E027: "Missing ']' to match '[' from line {a}.", + E028: "Illegal comma.", + E029: "Unclosed string.", + + // Everything else + E030: "Expected an identifier and instead saw '{a}'.", + E031: "Bad assignment.", // FIXME: Rephrase + E032: "Expected a small integer or 'false' and instead saw '{a}'.", + E033: "Expected an operator and instead saw '{a}'.", + E034: "get/set are ES5 features.", + E035: "Missing property name.", + E036: "Expected to see a statement and instead saw a block.", + E037: null, + E038: null, + E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.", + E040: "Each value should have its own case label.", + E041: "Unrecoverable syntax error.", + E042: "Stopping.", + E043: "Too many errors.", + E044: null, + E045: "Invalid for each loop.", + E046: "Yield expressions may only occur within generator functions.", + E047: null, + E048: "{a} declaration not directly within block.", + E049: "A {a} cannot be named '{b}'.", + E050: "Mozilla requires the yield expression to be parenthesized here.", + E051: null, + E052: "Unclosed template literal.", + E053: "{a} declarations are only allowed at the top level of module scope.", + E054: "Class properties must be methods. Expected '(' but instead saw '{a}'.", + E055: "The '{a}' option cannot be set after any executable code.", + E056: "'{a}' was used before it was declared, which is illegal for '{b}' variables.", + E057: "Invalid meta property: '{a}.{b}'.", + E058: "Missing semicolon.", + E059: "Incompatible values for the '{a}' and '{b}' linting options.", + E060: "Non-callable values cannot be used as the second operand to instanceof.", + E061: "Invalid position for 'yield' expression (consider wrapping in parenthesis).", + E062: "Rest parameter does not a support default value.", + E063: "Super property may only be used within method bodies.", + E064: "Super call may only be used within class method bodies.", + E065: "Functions defined outside of strict mode with non-simple parameter lists may not " + + "enable strict mode.", + E066: "Asynchronous iteration is only available with for-of loops.", + E067: "Malformed numeric literal: '{a}'.", + E068: "Decimals with leading zeros are not allowed in strict mode.", + E069: "Duplicate exported binding: '{a}'.", + E070: "import.meta may only be used in module code." +}; + +var warnings = { + W001: "'hasOwnProperty' is a really bad name.", + W002: "Value of '{a}' may be overwritten in IE 8 and earlier.", + W003: "'{a}' was used before it was defined.", + W004: "'{a}' is already defined.", + W005: "A dot following a number can be confused with a decimal point.", + W006: "Confusing minuses.", + W007: "Confusing plusses.", + W008: "A leading decimal point can be confused with a dot: '{a}'.", + W009: "The array literal notation [] is preferable.", + W010: "The object literal notation {} is preferable.", + W011: null, + W012: null, + W013: null, + W014: "Misleading line break before '{a}'; readers may interpret this as an expression boundary.", + W015: null, + W016: "Unexpected use of '{a}'.", + W017: "Bad operand.", + W018: "Confusing use of '{a}'.", + W019: "Use the isNaN function to compare with NaN.", + W020: "Read only.", + W021: "Reassignment of '{a}', which is a {b}. " + + "Use 'var' or 'let' to declare bindings that may change.", + W022: "Do not assign to the exception parameter.", + W023: null, + W024: "Expected an identifier and instead saw '{a}' (a reserved word).", + W025: "Missing name in function declaration.", + W026: "Inner functions should be listed at the top of the outer function.", + W027: "Unreachable '{a}' after '{b}'.", + W028: "Label '{a}' on {b} statement.", + W030: "Expected an assignment or function call and instead saw an expression.", + W031: "Do not use 'new' for side effects.", + W032: "Unnecessary semicolon.", + W033: "Missing semicolon.", + W034: "Unnecessary directive \"{a}\".", + W035: "Empty block.", + W036: "Unexpected /*member '{a}'.", + W037: "'{a}' is a statement label.", + W038: "'{a}' used out of scope.", + W039: null, + W040: "If a strict mode function is executed using function invocation, " + + "its 'this' value will be undefined.", + W041: null, + W042: "Avoid EOL escaping.", + W043: "Bad escaping of EOL. Use option multistr if needed.", + W044: "Bad or unnecessary escaping.", /* TODO(caitp): remove W044 */ + W045: "Value described by numeric literal cannot be accurately " + + "represented with a number value: '{a}'.", + W046: "Don't use extra leading zeros '{a}'.", + W047: "A trailing decimal point can be confused with a dot: '{a}'.", + W048: "Unexpected control character in regular expression.", + W049: "Unexpected escaped character '{a}' in regular expression.", + W050: "JavaScript URL.", + W051: "Variables should not be deleted.", + W052: "Unexpected '{a}'.", + W053: "Do not use {a} as a constructor.", + W054: "The Function constructor is a form of eval.", + W055: "A constructor name should start with an uppercase letter.", + W056: "Bad constructor.", + W057: "Weird construction. Is 'new' necessary?", + W058: "Missing '()' invoking a constructor.", + W059: "Avoid arguments.{a}.", + W060: "document.write can be a form of eval.", + W061: "eval can be harmful.", + W062: "Wrap an immediate function invocation in parens " + + "to assist the reader in understanding that the expression " + + "is the result of a function, and not the function itself.", + W063: "Math is not a function.", + W064: "Missing 'new' prefix when invoking a constructor.", + W065: "Missing radix parameter.", + W066: "Implied eval. Consider passing a function instead of a string.", + W067: "Unorthodox function invocation.", + W068: "Wrapping non-IIFE function literals in parens is unnecessary.", + W069: "['{a}'] is better written in dot notation.", + W070: "Extra comma. (it breaks older versions of IE)", + W071: "This function has too many statements. ({a})", + W072: "This function has too many parameters. ({a})", + W073: "Blocks are nested too deeply. ({a})", + W074: "This function's cyclomatic complexity is too high. ({a})", + W075: "Duplicate {a} '{b}'.", + W076: "Unexpected parameter '{a}' in get {b} function.", + W077: "Expected a single parameter in set {a} function.", + W078: "Setter is defined without getter.", + W079: "Redefinition of '{a}'.", + W080: "It's not necessary to initialize '{a}' to 'undefined'.", + W081: null, + W082: "Function declarations should not be placed in blocks. " + + "Use a function expression or move the statement to the top of " + + "the outer function.", + W083: "Functions declared within loops referencing an outer scoped " + + "variable may lead to confusing semantics. ({a})", + W084: "Assignment in conditional expression", + W085: "Don't use 'with'.", + W086: "Expected a 'break' statement before '{a}'.", + W087: "Forgotten 'debugger' statement?", + W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.", + W089: "The body of a for in should be wrapped in an if statement to filter " + + "unwanted properties from the prototype.", + W090: "'{a}' is not a statement label.", + W091: null, + W093: "Did you mean to return a conditional instead of an assignment?", + W094: "Unexpected comma.", + W095: "Expected a string and instead saw {a}.", + W096: "The '{a}' key may produce unexpected results.", + W097: "Use the function form of \"use strict\".", + W098: "'{a}' is defined but never used.", + W099: null, + W100: null, + W101: "Line is too long.", + W102: null, + W103: "The '{a}' property is deprecated.", + W104: "'{a}' is available in ES{b} (use 'esversion: {b}') or Mozilla JS extensions (use moz).", + W105: null, + W106: "Identifier '{a}' is not in camel case.", + W107: "Script URL.", + W108: "Strings must use doublequote.", + W109: "Strings must use singlequote.", + W110: "Mixed double and single quotes.", + W112: "Unclosed string.", + W113: "Control character in string: {a}.", + W114: "Avoid {a}.", + W115: "Octal literals are not allowed in strict mode.", + W116: "Expected '{a}' and instead saw '{b}'.", + W117: "'{a}' is not defined.", + W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).", + W119: "'{a}' is only available in ES{b} (use 'esversion: {b}').", + W120: "You might be leaking a variable ({a}) here.", + W121: "Extending prototype of native object: '{a}'.", + W122: "Invalid typeof value '{a}'", + W123: "'{a}' is already defined in outer scope.", + W124: "A generator function should contain at least one yield expression.", + W125: "This line contains non-breaking spaces: http://jshint.com/docs/options/#nonbsp", + W126: "Unnecessary grouping operator.", + W127: "Unexpected use of a comma operator.", + W128: "Empty array elements require elision=true.", + W129: "'{a}' is defined in a future version of JavaScript. Use a " + + "different variable name to avoid migration issues.", + W130: "Invalid element after rest element.", + W131: "Invalid parameter after rest parameter.", + W132: "`var` declarations are forbidden. Use `let` or `const` instead.", + W133: "Invalid for-{a} loop left-hand-side: {b}.", + W134: "The '{a}' option is only available when linting ECMAScript {b} code.", + W135: "{a} may not be supported by non-browser environments.", + W136: "'{a}' must be in function scope.", + W137: "Empty destructuring: this is unnecessary and can be removed.", + W138: "Regular parameters should not come after default parameters.", + W139: "Function expressions should not be used as the second operand to instanceof.", + W140: "Missing comma.", + W141: "Empty {a}: this is unnecessary and can be removed.", + W142: "Empty {a}: consider replacing with `import '{b}';`.", + W143: "Assignment to properties of a mapped arguments object may cause " + + "unexpected changes to formal parameters.", + W144: "'{a}' is a non-standard language feature. Enable it using the '{b}' unstable option.", + W145: "Superfluous 'case' clause.", + W146: "Unnecessary `await` expression.", + W147: "Regular expressions should include the 'u' flag.", + W148: "Unnecessary RegExp 's' flag." +}; + +var info = { + I001: "Comma warnings can be turned off with 'laxcomma'.", + I002: null, + I003: "ES5 option is now set per default" +}; + +exports.errors = {}; +exports.warnings = {}; +exports.info = {}; + +_.each(errors, function(desc, code) { + exports.errors[code] = { code: code, desc: desc }; +}); + +_.each(warnings, function(desc, code) { + exports.warnings[code] = { code: code, desc: desc }; +}); + +_.each(info, function(desc, code) { + exports.info[code] = { code: code, desc: desc }; +}); + +},{"underscore":"/../../../jshint/node_modules/underscore/underscore-umd.js"}],"/../../../jshint/src/name-stack.js":[function(_dereq_,module,exports){ +/** + * The NameStack class is used to approximate function name inference as + * introduced by ECMAScript 2015. In that edition, the `name` property of + * function objects is set according to the function's syntactic form. For + * certain forms, this value depends on values available to the runtime during + * execution. For example: + * + * var fnName = function() {}; + * + * In the program code above, the function object's `name` property is set to + * `"fnName"` during execution. + * + * This general "name inference" behavior extends to a number of additional + * syntactic forms, not all of which can be implemented statically. `NameStack` + * is a support class representing a "best-effort" attempt to implement the + * specified behavior in cases where this may be done statically. + * + * For more information on this behavior, see the following blog post: + * https://bocoup.com/blog/whats-in-a-function-name + */ +"use strict"; + +function NameStack() { + this._stack = []; +} + +Object.defineProperty(NameStack.prototype, "length", { + get: function() { + return this._stack.length; + } +}); + +/** + * Create a new entry in the stack. Useful for tracking names across + * expressions. + */ +NameStack.prototype.push = function() { + this._stack.push(null); +}; + +/** + * Discard the most recently-created name on the stack. + */ +NameStack.prototype.pop = function() { + this._stack.pop(); +}; + +/** + * Update the most recent name on the top of the stack. + * + * @param {object} token The token to consider as the source for the most + * recent name. + */ +NameStack.prototype.set = function(token) { + this._stack[this.length - 1] = token; +}; + +/** + * Generate a string representation of the most recent name. + * + * @returns {string} + */ +NameStack.prototype.infer = function() { + var nameToken = this._stack[this.length - 1]; + var prefix = ""; + var type; + + // During expected operation, the topmost entry on the stack will only + // reflect the current function's name when the function is declared without + // the `function` keyword (i.e. for in-line accessor methods). In other + // cases, the `function` expression itself will introduce an empty entry on + // the top of the stack, and this should be ignored. + if (!nameToken || nameToken.type === "class") { + nameToken = this._stack[this.length - 2]; + } + + if (!nameToken) { + return "(empty)"; + } + + type = nameToken.type; + + if (type !== "(string)" && type !== "(number)" && type !== "(identifier)" && type !== "default") { + return "(expression)"; + } + + if (nameToken.accessorType) { + prefix = nameToken.accessorType + " "; + } + + return prefix + nameToken.value; +}; + +module.exports = NameStack; + +},{}],"/../../../jshint/src/options.js":[function(_dereq_,module,exports){ +"use strict"; + +// These are the JSHint boolean options. +exports.bool = { + enforcing: { + + /** + * This option prohibits the use of bitwise operators such as `^` (XOR), + * `|` (OR) and others. Bitwise operators are very rare in JavaScript + * programs and quite often `&` is simply a mistyped `&&`. + */ + bitwise : true, + + /** + * + * This options prohibits overwriting prototypes of native objects such as + * `Array`, `Date` and so on. + * + * // jshint freeze:true + * Array.prototype.count = function (value) { return 4; }; + * // -> Warning: Extending prototype of native object: 'Array'. + */ + freeze : true, + + /** + * This option allows you to force all variable names to use either + * camelCase style or UPPER_CASE with underscores. + * + * @deprecated JSHint is limiting its scope to issues of code correctness. + * If you would like to enforce rules relating to code style, + * check out [the JSCS + * project](https://github.com/jscs-dev/node-jscs). + */ + camelcase : true, + + /** + * This option requires you to always put curly braces around blocks in + * loops and conditionals. JavaScript allows you to omit curly braces when + * the block consists of only one statement, for example: + * + * while (day) + * shuffle(); + * + * However, in some circumstances, it can lead to bugs (you'd think that + * `sleep()` is a part of the loop while in reality it is not): + * + * while (day) + * shuffle(); + * sleep(); + */ + curly : true, + + /** + * This options prohibits the use of `==` and `!=` in favor of `===` and + * `!==`. The former try to coerce values before comparing them which can + * lead to some unexpected results. The latter don't do any coercion so + * they are generally safer. If you would like to learn more about type + * coercion in JavaScript, we recommend [Truth, Equality and + * JavaScript](http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/) + * by Angus Croll. + */ + eqeqeq : true, + + /** + * This option enables warnings about the use of identifiers which are + * defined in future versions of JavaScript. Although overwriting them has + * no effect in contexts where they are not implemented, this practice can + * cause issues when migrating codebases to newer versions of the language. + */ + futurehostile: true, + + /** + * This option tells JSHint that your code needs to adhere to ECMAScript 3 + * specification. Use this option if you need your program to be executable + * in older browsers—such as Internet Explorer 6/7/8/9—and other legacy + * JavaScript environments. + * + * @deprecated Use `esversion: 3` instead. + */ + es3 : true, + + /** + * This option enables syntax first defined in [the ECMAScript 5.1 + * specification](http://es5.github.io/). This includes allowing reserved + * keywords as object properties. + * + * @deprecated Use `esversion: 5` instead. + */ + es5 : true, + + /** + * This option requires all `for in` loops to filter object's items. The + * for in statement allows for looping through the names of all of the + * properties of an object including those inherited through the prototype + * chain. This behavior can lead to unexpected items in your object so it + * is generally safer to always filter inherited properties out as shown in + * the example: + * + * for (key in obj) { + * if (obj.hasOwnProperty(key)) { + * // We are sure that obj[key] belongs to the object and was not inherited. + * } + * } + * + * For more in-depth understanding of `for in` loops in JavaScript, read + * [Exploring JavaScript for-in + * loops](http://javascriptweblog.wordpress.com/2011/01/04/exploring-javascript-for-in-loops/) + * by Angus Croll. + */ + forin : true, + + /** + * This option prohibits the use of immediate function invocations without + * wrapping them in parentheses. Wrapping parentheses assists readers of + * your code in understanding that the expression is the result of a + * function, and not the function itself. + * + * @deprecated JSHint is limiting its scope to issues of code correctness. + * If you would like to enforce rules relating to code style, + * check out [the JSCS + * project](https://github.com/jscs-dev/node-jscs). + */ + immed : true, + + /** + * This option prohibits unnecessary clauses within `switch` statements, + * e.g. + * + * switch (x) { + * case 1: + * default: + * z(); + * } + * + * While clauses like these are techincally valid, they do not effect + * program behavior and may indicate an erroneous refactoring. + */ + leanswitch : true, + + /** + * This option requires you to capitalize names of constructor functions. + * Capitalizing functions that are intended to be used with `new` operator + * is just a convention that helps programmers to visually distinguish + * constructor functions from other types of functions to help spot + * mistakes when using `this`. + * + * Not doing so won't break your code in any browsers or environments but + * it will be a bit harder to figure out—by reading the code—if the + * function was supposed to be used with or without new. And this is + * important because when the function that was intended to be used with + * `new` is used without it, `this` will point to the global object instead + * of a new object. + * + * @deprecated JSHint is limiting its scope to issues of code correctness. + * If you would like to enforce rules relating to code style, + * check out [the JSCS + * project](https://github.com/jscs-dev/node-jscs). + */ + newcap : true, + + /** + * This option prohibits the use of `arguments.caller` and + * `arguments.callee`. Both `.caller` and `.callee` make quite a few + * optimizations impossible so they were deprecated in future versions of + * JavaScript. In fact, ECMAScript 5 forbids the use of `arguments.callee` + * in strict mode. + */ + noarg : true, + + /** + * This option prohibits the use of the comma operator. When misused, the + * comma operator can obscure the value of a statement and promote + * incorrect code. + */ + nocomma : true, + + /** + * This option warns when you have an empty block in your code. JSLint was + * originally warning for all empty blocks and we simply made it optional. + * There were no studies reporting that empty blocks in JavaScript break + * your code in any way. + * + * @deprecated JSHint is limiting its scope to issues of code correctness. + * If you would like to enforce rules relating to code style, + * check out [the JSCS + * project](https://github.com/jscs-dev/node-jscs). + */ + noempty : true, + + /** + * This option warns about "non-breaking whitespace" characters. These + * characters can be entered with option-space on Mac computers and have a + * potential of breaking non-UTF8 web pages. + */ + nonbsp : true, + + /** + * This option prohibits the use of constructor functions for side-effects. + * Some people like to call constructor functions without assigning its + * result to any variable: + * + * new MyConstructor(); + * + * There is no advantage in this approach over simply calling + * `MyConstructor` since the object that the operator `new` creates isn't + * used anywhere so you should generally avoid constructors like this one. + */ + nonew : true, + + + /** + * Async functions resolve on their return value. In most cases, this makes + * returning the result of an AwaitExpression (which is itself a Promise + * instance) unnecessary. For clarity, it's often preferable to return the + * result of the asynchronous operation directly. The notable exception is + * within the `try` clause of a TryStatement--for more, see "await vs + * return vs return await": + * + * https://jakearchibald.com/2017/await-vs-return-vs-return-await/ + */ + noreturnawait: true, + + /** + * This option enables warnings for regular expressions which do not + * include the "u" flag. The "u" flag extends support for Unicode and also + * enables more strict parsing rules. JSHint will enforce these rules even + * if it is executed in a JavaScript engine which does not support the "u" + * flag. + */ + regexpu : true, + + /** + * This option prohibits the use of explicitly undeclared variables. This + * option is very useful for spotting leaking and mistyped variables. + * + * // jshint undef:true + * + * function test() { + * var myVar = 'Hello, World'; + * console.log(myvar); // Oops, typoed here. JSHint with undef will complain + * } + * + * If your variable is defined in another file, you can use the `global` + * directive to tell JSHint about it. + */ + undef : true, + + /** + * This option prohibits the use of the grouping operator when it is not + * strictly required. Such usage commonly reflects a misunderstanding of + * unary operators, for example: + * + * // jshint singleGroups: true + * + * delete(obj.attr); // Warning: Unnecessary grouping operator. + */ + singleGroups: false, + + /** + * When set to true, the use of VariableStatements are forbidden. + * For example: + * + * // jshint varstmt: true + * + * var a; // Warning: `var` declarations are forbidden. Use `let` or `const` instead. + */ + varstmt: false, + + /** + * This option is a short hand for the most strict JSHint configuration as + * available in JSHint version 2.6.3. It enables all enforcing options and + * disables all relaxing options that were defined in that release. + * + * @deprecated The option cannot be maintained without automatically opting + * users in to new features. This can lead to unexpected + * warnings/errors in when upgrading between minor versions of + * JSHint. + */ + enforceall : false, + + /** + * This option warns when a comma is not placed after the last element in an + * array or object literal. Due to bugs in old versions of IE, trailing + * commas used to be discouraged, but since ES5 their semantics were + * standardized. (See + * [#11.1.4](http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.4) and + * [#11.1.5](http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5).) + * Now, they help to prevent the same [visual + * ambiguities](http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.2) + * that the strict usage of semicolons helps prevent. + * + * For example, this code might have worked last Tuesday: + * + * [ + * b + c + * ].forEach(print); + * + * But if one adds an element to the array and forgets to compensate for the + * missing comma, no syntax error is thrown, and a linter cannot determine + * if this was a mistake or an intentional function invocation. + * + * [ + * b + c + * (d + e) + * ].forEach(print); + * + * If one always appends a list item with a comma, this ambiguity cannot + * occur: + * + * [ + * b + c, + * ].forEach(print); + * + * [ + * b + c, + * (d + e), + * ].forEach(print); + */ + trailingcomma: false + }, + relaxing: { + + /** + * This option suppresses warnings about missing semicolons. There is a lot + * of FUD about semicolon spread by quite a few people in the community. + * The common myths are that semicolons are required all the time (they are + * not) and that they are unreliable. JavaScript has rules about semicolons + * which are followed by *all* browsers so it is up to you to decide + * whether you should or should not use semicolons in your code. + * + * For more information about semicolons in JavaScript read [An Open Letter + * to JavaScript Leaders Regarding + * Semicolons](http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding) + * by Isaac Schlueter and [JavaScript Semicolon + * Insertion](http://inimino.org/~inimino/blog/javascript_semicolons). + */ + asi : true, + + /** + * This option suppresses warnings about multi-line strings. Multi-line + * strings can be dangerous in JavaScript because all hell breaks loose if + * you accidentally put a whitespace in between the escape character (`\`) + * and a new line. + * + * Note that even though this option allows correct multi-line strings, it + * still warns about multi-line strings without escape characters or with + * anything in between the escape character and a whitespace. + * + * // jshint multistr:true + * + * var text = "Hello\ + * World"; // All good. + * + * text = "Hello + * World"; // Warning, no escape character. + * + * text = "Hello\ + * World"; // Warning, there is a space after \ + * + * @deprecated JSHint is limiting its scope to issues of code correctness. + * If you would like to enforce rules relating to code style, + * check out [the JSCS + * project](https://github.com/jscs-dev/node-jscs). + */ + multistr : true, + + /** + * This option suppresses warnings about the `debugger` statements in your + * code. + */ + debug : true, + + /** + * This option suppresses warnings about the use of assignments in cases + * where comparisons are expected. More often than not, code like `if (a = + * 10) {}` is a typo. However, it can be useful in cases like this one: + * + * for (var i = 0, person; person = people[i]; i++) {} + * + * You can silence this error on a per-use basis by surrounding the assignment + * with parenthesis, such as: + * + * for (var i = 0, person; (person = people[i]); i++) {} + */ + boss : true, + + /** + * This option suppresses warnings about the use of `eval`. The use of + * `eval` is discouraged because it can make your code vulnerable to + * various injection attacks and it makes it hard for JavaScript + * interpreter to do certain optimizations. + */ + evil : true, + + /** + * This option suppresses warnings about declaring variables inside + * of control structures while accessing them later from the outside. + * Even though identifiers declared with `var` have two real scopes—global + * and function—such practice leads to confusion among people new to + * the language and hard-to-debug bugs. This is why, by default, JSHint + * warns about variables that are used outside of their intended scope. + * + * function test() { + * if (true) { + * var x = 0; + * } + * + * x += 1; // Default: 'x' used out of scope. + * // No warning when funcscope:true + * } + */ + funcscope : true, + + /** + * This option suppresses warnings about the use of global strict mode. + * Global strict mode can break third-party widgets so it is not + * recommended. + * + * For more info about strict mode see the `strict` option. + * + * @deprecated Use `strict: "global"`. + */ + globalstrict: true, + + /** + * This option suppresses warnings about the `__iterator__` property. This + * property is not supported by all browsers so use it carefully. + */ + iterator : true, + + /** + * This option suppresses warnings about invalid `typeof` operator values. + * This operator has only [a limited set of possible return + * values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof). + * By default, JSHint warns when you compare its result with an invalid + * value which often can be a typo. + * + * // 'fuction' instead of 'function' + * if (typeof a == "fuction") { // Invalid typeof value 'fuction' + * // ... + * } + * + * Do not use this option unless you're absolutely sure you don't want + * these checks. + */ + notypeof : true, + + /** + * This option prohibits the use of unary increment and decrement + * operators. Some people think that `++` and `--` reduces the quality of + * their coding styles and there are programming languages—such as + * Python—that go completely without these operators. + */ + plusplus : true, + + /** + * This option suppresses warnings about the `__proto__` property. + */ + proto : true, + + /** + * This option suppresses warnings about the use of script-targeted + * URLs—such as `javascript:...`. + */ + scripturl : true, + + /** + * This option suppresses warnings about using `[]` notation when it can be + * expressed in dot notation: `person['name']` vs. `person.name`. + * + * @deprecated JSHint is limiting its scope to issues of code correctness. + * If you would like to enforce rules relating to code style, + * check out [the JSCS + * project](https://github.com/jscs-dev/node-jscs). + */ + sub : true, + + /** + * This option suppresses warnings about "weird" constructions like + * `new function () { ... }` and `new Object;`. Such constructions are + * sometimes used to produce singletons in JavaScript: + * + * var singleton = new function() { + * var privateVar; + * + * this.publicMethod = function () {} + * this.publicMethod2 = function () {} + * }; + */ + supernew : true, + + /** + * This option suppresses most of the warnings about possibly unsafe line + * breakings in your code. It doesn't suppress warnings about comma-first + * coding style. To suppress those you have to use `laxcomma` (see below). + * + * @deprecated JSHint is limiting its scope to issues of code correctness. + * If you would like to enforce rules relating to code style, + * check out [the JSCS + * project](https://github.com/jscs-dev/node-jscs). + */ + laxbreak : true, + + /** + * This option suppresses warnings about comma-first coding style: + * + * var obj = { + * name: 'Anton' + * , handle: 'valueof' + * , role: 'SW Engineer' + * }; + * + * @deprecated JSHint is limiting its scope to issues of code correctness. + * If you would like to enforce rules relating to code style, + * check out [the JSCS + * project](https://github.com/jscs-dev/node-jscs). + */ + laxcomma : true, + + /** + * This option suppresses warnings about possible strict violations when + * the code is running in strict mode and you use `this` in a + * non-constructor function. You should use this option—in a function scope + * only—when you are positive that your use of `this` is valid in the + * strict mode (for example, if you call your function using + * `Function.call`). + * + * **Note:** This option can be used only inside of a function scope. + * JSHint will fail with an error if you will try to set this option + * globally. + */ + validthis : true, + + /** + * This option suppresses warnings about the use of the `with` statement. + * The semantics of the `with` statement can cause confusion among + * developers and accidental definition of global variables. + * + * More info: + * + * * [with Statement Considered + * Harmful](http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/) + */ + withstmt : true, + + /** + * This options tells JSHint that your code uses Mozilla JavaScript + * extensions. Unless you develop specifically for the Firefox web browser + * you don't need this option. + * + * More info: + * + * * [New in JavaScript + * 1.7](https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.7) + */ + moz : true, + + /** + * This option suppresses warnings about generator functions with no + * `yield` statement in them. + */ + noyield : true, + + /** + * This option suppresses warnings about `== null` comparisons. Such + * comparisons are often useful when you want to check if a variable is + * `null` or `undefined`. + */ + eqnull : true, + + /** + * This option suppresses warnings about missing semicolons, but only when + * the semicolon is omitted for the last statement in a one-line block: + * + * var name = (function() { return 'Anton' }()); + * + * This is a very niche use case that is useful only when you use automatic + * JavaScript code generators. + */ + lastsemic : true, + + /** + * This option suppresses warnings about functions inside of loops. + * Defining functions inside of loops can lead to bugs such as this one: + * + * var nums = []; + * + * for (var i = 0; i < 10; i++) { + * nums[i] = function (j) { + * return i + j; + * }; + * } + * + * nums[0](2); // Prints 12 instead of 2 + * + * To fix the code above you need to copy the value of `i`: + * + * var nums = []; + * + * for (var i = 0; i < 10; i++) { + * (function (i) { + * nums[i] = function (j) { + * return i + j; + * }; + * }(i)); + * } + */ + loopfunc : true, + + /** + * This option suppresses warnings about the use of expressions where + * normally you would expect to see assignments or function calls. Most of + * the time, such code is a typo. However, it is not forbidden by the spec + * and that's why this warning is optional. + */ + expr : true, + + /** + * This option tells JSHint that your code uses ECMAScript 6 specific + * syntax. Note that not all browsers implement these features. + * + * More info: + * + * * [Specification for ECMAScript + * 6](http://www.ecma-international.org/ecma-262/6.0/index.html) + * + * @deprecated Use `esversion: 6` instead. + */ + esnext : true, + + /** + * This option tells JSHint that your code uses ES3 array elision elements, + * or empty elements (for example, `[1, , , 4, , , 7]`). + */ + elision : true, + }, + + // Third party globals + environments: { + + /** + * This option defines globals exposed by the + * [MooTools](http://mootools.net/) JavaScript framework. + */ + mootools : true, + + /** + * This option defines globals exposed by + * [CouchDB](http://couchdb.apache.org/). CouchDB is a document-oriented + * database that can be queried and indexed in a MapReduce fashion using + * JavaScript. + */ + couch : true, + + /** + * This option defines globals exposed by [the Jasmine unit testing + * framework](https://jasmine.github.io/). + */ + jasmine : true, + + /** + * This option defines globals exposed by the [jQuery](http://jquery.com/) + * JavaScript library. + */ + jquery : true, + + /** + * This option defines globals available when your code is running inside + * of the Node runtime environment. [Node.js](http://nodejs.org/) is a + * server-side JavaScript environment that uses an asynchronous + * event-driven model. This option also skips some warnings that make sense + * in the browser environments but don't make sense in Node such as + * file-level `use strict` pragmas and `console.log` statements. + */ + node : true, + + /** + * This option defines globals exposed by [the QUnit unit testing + * framework](http://qunitjs.com/). + */ + qunit : true, + + /** + * This option defines globals available when your code is running inside + * of the Rhino runtime environment. [Rhino](http://www.mozilla.org/rhino/) + * is an open-source implementation of JavaScript written entirely in Java. + */ + rhino : true, + + /** + * This option defines globals exposed by [the ShellJS + * library](http://documentup.com/arturadib/shelljs). + */ + shelljs : true, + + /** + * This option defines globals exposed by the + * [Prototype](http://www.prototypejs.org/) JavaScript framework. + */ + prototypejs : true, + + /** + * This option defines globals exposed by the [YUI](http://yuilibrary.com/) + * JavaScript framework. + */ + yui : true, + + /** + * This option defines globals exposed by the "BDD" and "TDD" UIs of the + * [Mocha unit testing framework](http://mochajs.org/). + */ + mocha : true, + + /** + * This option informs JSHint that the input code describes an ECMAScript 6 + * module. All module code is interpreted as strict mode code. + */ + module : true, + + /** + * This option defines globals available when your code is running as a + * script for the [Windows Script + * Host](http://en.wikipedia.org/wiki/Windows_Script_Host). + */ + wsh : true, + + /** + * This option defines globals available when your code is running inside + * of a Web Worker. [Web + * Workers](https://developer.mozilla.org/en/Using_web_workers) provide a + * simple means for web content to run scripts in background threads. + */ + worker : true, + + /** + * This option defines non-standard but widely adopted globals such as + * `escape` and `unescape`. + */ + nonstandard : true, + + /** + * This option defines globals exposed by modern browsers: all the way from + * good old `document` and `navigator` to the HTML5 `FileReader` and other + * new developments in the browser world. + * + * **Note:** This option doesn't expose variables like `alert` or + * `console`. See option `devel` for more information. + */ + browser : true, + + /** + * This option defines globals available when using [the Browserify + * tool](http://browserify.org/) to build a project. + */ + browserify : true, + + /** + * This option defines globals that are usually used for logging poor-man's + * debugging: `console`, `alert`, etc. It is usually a good idea to not + * ship them in production because, for example, `console.log` breaks in + * legacy versions of Internet Explorer. + */ + devel : true, + + /** + * This option defines globals exposed by the [Dojo + * Toolkit](http://dojotoolkit.org/). + */ + dojo : true, + + /** + * This option defines globals for typed array constructors. + * + * More info: + * + * * [JavaScript typed + * arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) + */ + typed : true, + + /** + * This option defines globals available when your core is running inside + * of the PhantomJS runtime environment. [PhantomJS](http://phantomjs.org/) + * is a headless WebKit scriptable with a JavaScript API. It has fast and + * native support for various web standards: DOM handling, CSS selector, + * JSON, Canvas, and SVG. + */ + phantom : true + }, + + // Obsolete options + obsolete: { + onecase : true, // if one case switch statements should be allowed + regexp : true, // if the . should not be allowed in regexp literals + regexdash : true // if unescaped first/last dash (-) inside brackets + // should be tolerated + } +}; + +// These are the JSHint options that can take any value +// (we use this object to detect invalid options) +exports.val = { + + /** + * This option lets you set the maximum length of a line. + * + * @deprecated JSHint is limiting its scope to issues of code correctness. If + * you would like to enforce rules relating to code style, check + * out [the JSCS project](https://github.com/jscs-dev/node-jscs). + */ + maxlen : false, + + /** + * This option sets a specific tab width for your code. + * + * @deprecated JSHint is limiting its scope to issues of code correctness. If + * you would like to enforce rules relating to code style, check + * out [the JSCS project](https://github.com/jscs-dev/node-jscs). + */ + indent : false, + + /** + * This options allows you to set the maximum amount of errors JSHint will + * produce before giving up. Default is 50. + */ + maxerr : false, + + /** + * This option allows you to control which variables JSHint considers to be + * implicitly defined in the environment. Configure it with an array of + * string values. Prefixing a variable name with a hyphen (-) character will + * remove that name from the collection of predefined variables. + * + * JSHint will consider variables declared in this way to be read-only. + * + * This option cannot be specified in-line; it may only be used via the + * JavaScript API or from an external configuration file. + */ + predef : false, + + /** + * This option can be used to specify a white list of global variables that + * are not formally defined in the source code. This is most useful when + * combined with the `undef` option in order to suppress warnings for + * project-specific global variables. + * + * Setting an entry to `true` enables reading and writing to that variable. + * Setting it to `false` will trigger JSHint to consider that variable + * read-only. + * + * See also the "environment" options: a set of options to be used as short + * hand for enabling global variables defined in common JavaScript + * environments. + * + * To configure `globals` within an individual file, see [Inline + * Configuration](http://jshint.com/docs/#inline-configuration). + */ + globals : false, + + /** + * This option enforces the consistency of quotation marks used throughout + * your code. It accepts three values: `true` if you don't want to enforce + * one particular style but want some consistency, `"single"` if you want to + * allow only single quotes and `"double"` if you want to allow only double + * quotes. + * + * @deprecated JSHint is limiting its scope to issues of code correctness. If + * you would like to enforce rules relating to code style, check + * out [the JSCS project](https://github.com/jscs-dev/node-jscs). + */ + quotmark : false, + + scope : false, + + /** + * This option lets you set the max number of statements allowed per function: + * + * // jshint maxstatements:4 + * + * function main() { + * var i = 0; + * var j = 0; + * + * // Function declarations count as one statement. Their bodies + * // don't get taken into account for the outer function. + * function inner() { + * var i2 = 1; + * var j2 = 1; + * + * return i2 + j2; + * } + * + * j = i + j; + * return j; // JSHint: Too many statements per function. (5) + * } + */ + maxstatements: false, + + /** + * This option lets you control how nested do you want your blocks to be: + * + * // jshint maxdepth:2 + * + * function main(meaning) { + * var day = true; + * + * if (meaning === 42) { + * while (day) { + * shuffle(); + * + * if (tired) { // JSHint: Blocks are nested too deeply (3). + * sleep(); + * } + * } + * } + * } + */ + maxdepth : false, + + /** + * This option lets you set the max number of formal parameters allowed per + * function: + * + * // jshint maxparams:3 + * + * function login(request, onSuccess) { + * // ... + * } + * + * // JSHint: Too many parameters per function (4). + * function logout(request, isManual, whereAmI, onSuccess) { + * // ... + * } + */ + maxparams : false, + + /** + * This option lets you control cyclomatic complexity throughout your code. + * Cyclomatic complexity measures the number of linearly independent paths + * through a program's source code. Read more about [cyclomatic complexity on + * Wikipedia](http://en.wikipedia.org/wiki/Cyclomatic_complexity). + */ + maxcomplexity: false, + + /** + * This option suppresses warnings about variable shadowing i.e. declaring a + * variable that had been already declared somewhere in the outer scope. + * + * - "inner" - check for variables defined in the same scope only + * - "outer" - check for variables defined in outer scopes as well + * - false - same as inner + * - true - allow variable shadowing + */ + shadow : false, + + /** + * This option requires the code to run in ECMAScript 5's strict mode. + * [Strict mode](https://developer.mozilla.org/en/JavaScript/Strict_mode) + * is a way to opt in to a restricted variant of JavaScript. Strict mode + * eliminates some JavaScript pitfalls that didn't cause errors by changing + * them to produce errors. It also fixes mistakes that made it difficult + * for the JavaScript engines to perform certain optimizations. + * + * - "global" - there must be a `"use strict";` directive at global level + * - "implied" - lint the code as if there is the `"use strict";` directive + * - false - disable warnings about strict mode + * - true - there must be a `"use strict";` directive at function level; + * this is preferable for scripts intended to be loaded in web + * browsers directly because enabling strict mode globally + * could adversely effect other scripts running on the same + * page + */ + strict : true, + + /** + * This option warns when you define and never use your variables. It is very + * useful for general code cleanup, especially when used in addition to + * `undef`. + * + * // jshint unused:true + * + * function test(a, b) { + * var c, d = 2; + * + * return a + d; + * } + * + * test(1, 2); + * + * // Line 3: 'b' was defined but never used. + * // Line 4: 'c' was defined but never used. + * + * In addition to that, this option will warn you about unused global + * variables declared via the `global` directive. + * + * When set to `true`, unused parameters that are followed by a used + * parameter will not produce warnings. This option can be set to `vars` to + * only check for variables, not function parameters, or `strict` to check + * all variables and parameters. + */ + unused : true, + + /** + * This option prohibits the use of a variable before it was defined. + * JavaScript has function scope only and, in addition to that, all variables + * are always moved—or hoisted— to the top of the function. This behavior can + * lead to some very nasty bugs and that's why it is safer to always use + * variable only after they have been explicitly defined. + * + * Setting this option to "nofunc" will allow function declarations to be + * ignored. + * + * For more in-depth understanding of scoping and hoisting in JavaScript, + * read [JavaScript Scoping and + * Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting) + * by Ben Cherry. + */ + latedef : false, + + ignore : false, // start/end ignoring lines of code, bypassing the lexer + // start - start ignoring lines, including the current line + // end - stop ignoring lines, starting on the next line + // line - ignore warnings / errors for just a single line + // (this option does not bypass the lexer) + + ignoreDelimiters: false, // array of start/end delimiters used to ignore + // certain chunks from code + + /** + * This option is used to specify the ECMAScript version to which the code + * must adhere. It can assume one of the following values: + * - `3` - If you need your program to be executable + * in older browsers—such as Internet Explorer 6/7/8/9—and other legacy + * JavaScript environments + * - `5` - To enable syntax first defined in [the ECMAScript 5.1 + * specification](http://www.ecma-international.org/ecma-262/5.1/index.html). + * This includes allowing reserved keywords as object properties. + * - `6` - To tell JSHint that your code uses [ECMAScript + * 6](http://www.ecma-international.org/ecma-262/6.0/index.html) specific + * syntax. Note that not all browsers implement them. + * - `7` - To enable language features introduced by [ECMAScript + * 7](https://www.ecma-international.org/ecma-262/7.0/index.html). Notable + * additions: the exponentiation operator. + * - `8` - To enable language features introduced by [ECMAScript + * 8](https://www.ecma-international.org/ecma-262/8.0/index.html). Notable + * additions: async functions, shared memory, and atomics + * - `9` - To enable language features introduced by [ECMAScript + * 9](https://www.ecma-international.org/ecma-262/9.0/index.html). Notable + * additions: asynchronous iteration, rest/spread properties, and various + * RegExp extensions + * - `10` - To enable language features introduced by [ECMAScript + * 10](https://www.ecma-international.org/ecma-262/10.0/index.html). + * Notable additions: optional catch bindings. + * - `11` - To enable language features introduced by ECMAScript 11. Notable + * additions: "export * as ns from 'module'", `import.meta`, the nullish + * coalescing operator, the BigInt type, the `globalThis` binding, + * optional chaining, and dynamic import. + */ + esversion: 5 +}; + +/** + * Unstable options allow control for parsing and linting of proposed additions + * to the JavaScript language. Just like the language features they describe, + * the presence and behavior of these options is volatile; JSHint reserves the + * right to remove or modify them between major version releases. + */ +exports.unstable = { +}; + +// These are JSHint boolean options which are shared with JSLint +// where the definition in JSHint is opposite JSLint +exports.inverted = { + bitwise : true, + forin : true, + newcap : true, + plusplus: true, + regexp : true, + undef : true, + + // Inverted and renamed, use JSHint name here + eqeqeq : true, + strict : true +}; + +exports.validNames = Object.keys(exports.val) + .concat(Object.keys(exports.bool.relaxing)) + .concat(Object.keys(exports.bool.enforcing)) + .concat(Object.keys(exports.bool.obsolete)) + .concat(Object.keys(exports.bool.environments)) + .concat(["unstable"]); + +exports.unstableNames = Object.keys(exports.unstable); + +// These are JSHint boolean options which are shared with JSLint +// where the name has been changed but the effect is unchanged +exports.renamed = { + eqeq : "eqeqeq", + windows: "wsh", + sloppy : "strict" +}; + +exports.removed = { + nomen: true, + onevar: true, + passfail: true, + white: true, + gcl: true, + smarttabs: true, + trailing: true +}; + +// Add options here which should not be automatically enforced by +// `enforceall`. +exports.noenforceall = { + varstmt: true, + strict: true, + regexpu: true +}; + +},{}],"/../../../jshint/src/prod-params.js":[function(_dereq_,module,exports){ +/** + * This module defines a set of enum-like values intended for use as bit + * "flags" during parsing. The ECMAScript grammar defines a number of such + * "production parameters" to control how certain forms are parsed in context. + * JSHint implements additional parameters to facilitate detection of lint + * warnings. + * + * An equivalent implementation which described the context in terms of a + * "lookup table" object would be more idiomatic for a JavaScript project like + * JSHint. However, because the number of contexts scales with the number of + * expressions in the input program, this would have non-negligible impact on + * the process's memory footprint. + */ +module.exports = { + /** + * Enabled when parsing expressions within ES2015 "export" declarations, + * allowing otherwise-unreferenced bindings to be considered "used". + */ + export: 1, + + /** + * Enabled when parsing expressions within the head of `for` statements, + * allowing to distinguish between `for-in` and "C-style" `for` statements. + */ + noin: 2, + + /** + * Enabled when the expression begins the statement, allowing the parser to + * correctly select between the null denotation ("nud") and first null + * denotation ("fud") parsing strategy. + */ + initial: 4, + + preAsync: 8, + + async: 16, + + /** + * Enabled when any exception thrown by the expression will be caught by a + * TryStatement. + */ + tryClause: 32, + + /** + * Enabled when parsing the body of a generator function. + */ + yield: 64 +}; + +},{}],"/../../../jshint/src/reg.js":[function(_dereq_,module,exports){ +/* + * Regular expressions. Some of these are stupidly long. + */ + +/*jshint maxlen:1000 */ + +"use strict"; + +// Unsafe comment or string (ax) +exports.unsafeString = + /@cc|<\/?|script|\]\s*\]|<\s*!|</i; + +// Characters in strings that need escaping (nx and nxg) +exports.needEsc = + /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; + +exports.needEscGlobal = + /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + +// Star slash (lx) +exports.starSlash = /\*\//; + +// Identifier (ix) +exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; + +// JavaScript URL (jx) +exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i; + +// Catches /* falls through */ comments (ft) +exports.fallsThrough = /^\s*falls?\sthrough\s*$/; + +// very conservative rule (eg: only one space between the start of the comment and the first character) +// to relax the maxlen option +exports.maxlenException = /^(?:(?:\/\/|\/\*|\*) ?)?[^ ]+$/; + +// Node.js releases prior to version 8 include a version of the V8 engine which +// incorrectly interprets the character class escape `\s`. The following +// regular expression may be replaced with `/\s/` when JSHint removes support +// for Node.js versions prior to 8. +// Source: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp +exports.whitespace = /[ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/; + +exports.nonzeroDigit = /^[1-9]$/; + +exports.decimalDigit = /^[0-9]$/; + +exports.regexpSyntaxChars = /[\^$\\.*+?()[\]{}|]/; + +exports.regexpQuantifiers = /[*+?{]/; + +exports.regexpControlEscapes = /[fnrtv]/; + +exports.regexpCharClasses = /[dDsSwWpP]/; + +// Identifies the "dot" atom in regular expressions +exports.regexpDot = /(^|[^\\])(\\\\)*\./; + +},{}],"/../../../jshint/src/scope-manager.js":[function(_dereq_,module,exports){ +"use strict"; +/** + * A note on `__proto__`: + * + * This file uses ordinary objects to track identifiers that are observed in + * the input source code. It creates these objects using `Object.create` so + * that the tracking objects have no prototype, allowing the `__proto__` + * property to be used to store a value *without* triggering the invocation of + * the built-in `Object.prototype.__proto__` accessor method. Some environments + * (e.g. PhantomJS) do not implement the correct semantics for property + * enumeration. In those environments, methods like `Object.keys` and Lodash's + * `values` do not include the property name. This file includes a number of + * branches which ensure that JSHint behaves consistently in those + * environments. The branches must be ignored by the test coverage verification + * system because the workaround is not necessary in the environment where + * coverage is verified (i.e. Node.js). + */ + +var _ = _dereq_("underscore"); +_.slice = _dereq_("lodash.slice"); +var events = _dereq_("events"); + +// Used to denote membership in lookup tables (a primitive value such as `true` +// would be silently rejected for the property name "__proto__" in some +// environments) +var marker = {}; + +/** + * A factory function for creating scope managers. A scope manager tracks + * bindings, detecting when variables are referenced (through "usages"). + * + * @param {object} state - the global state object (see `state.js`) + * @param {Array} predefined - a set of binding names for built-in bindings + * provided by the environment + * @param {object} exported - a hash for binding names that are intended to be + * referenced in contexts beyond the current program + * code + * @param {object} declared - a hash for binding names that were defined as + * global bindings via linting configuration + * + * @returns {object} - a scope manager + */ +var scopeManager = function(state, predefined, exported, declared) { + + var _current; + var _scopeStack = []; + + function _newScope(type) { + _current = { + "(bindings)": Object.create(null), + "(usages)": Object.create(null), + "(labels)": Object.create(null), + "(parent)": _current, + "(type)": type, + "(params)": (type === "functionparams" || type === "catchparams") ? [] : null + }; + _scopeStack.push(_current); + } + + _newScope("global"); + _current["(predefined)"] = predefined; + + var _currentFunctBody = _current; // this is the block after the params = function + + var usedPredefinedAndGlobals = Object.create(null); + var impliedGlobals = Object.create(null); + var unuseds = []; + var esModuleExports = []; + var emitter = new events.EventEmitter(); + + function warning(code, token) { + emitter.emit("warning", { + code: code, + token: token, + data: _.slice(arguments, 2) + }); + } + + function error(code, token) { + emitter.emit("warning", { + code: code, + token: token, + data: _.slice(arguments, 2) + }); + } + + function _setupUsages(bindingName) { + if (!_current["(usages)"][bindingName]) { + _current["(usages)"][bindingName] = { + "(modified)": [], + "(reassigned)": [], + "(tokens)": [] + }; + } + } + + var _getUnusedOption = function(unused_opt) { + if (unused_opt === undefined) { + unused_opt = state.option.unused; + } + + if (unused_opt === true) { + unused_opt = "last-param"; + } + + return unused_opt; + }; + + var _warnUnused = function(name, tkn, type, unused_opt) { + var line = tkn.line; + var chr = tkn.from; + var raw_name = tkn.raw_text || name; + + unused_opt = _getUnusedOption(unused_opt); + + var warnable_types = { + "vars": ["var"], + "last-param": ["var", "param"], + "strict": ["var", "param", "last-param"] + }; + + if (unused_opt) { + if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) { + warning("W098", { line: line, from: chr }, raw_name); + } + } + + // inconsistent - see gh-1894 + if (unused_opt || type === "var") { + unuseds.push({ + name: name, + line: line, + character: chr + }); + } + }; + + /** + * Check the current scope for unused identifiers + */ + function _checkForUnused() { + if (_current["(type)"] !== "functionparams") { + var currentBindings = _current["(bindings)"]; + for (var bindingName in currentBindings) { + if (currentBindings[bindingName]["(type)"] !== "exception" && + currentBindings[bindingName]["(unused)"]) { + _warnUnused(bindingName, currentBindings[bindingName]["(token)"], "var"); + } + } + return; + } + + // Check the current scope for unused parameters and issue warnings as + // necessary. + var params = _current["(params)"]; + + var param = params.pop(); + var unused_opt; + + while (param) { + var binding = _current["(bindings)"][param]; + + unused_opt = _getUnusedOption(state.funct["(unusedOption)"]); + + // 'undefined' is a special case for the common pattern where `undefined` + // is used as a formal parameter name to defend against global + // re-assignment, e.g. + // + // (function(window, undefined) { + // })(); + if (param === "undefined") + return; + + if (binding["(unused)"]) { + _warnUnused(param, binding["(token)"], "param", state.funct["(unusedOption)"]); + } else if (unused_opt === "last-param") { + return; + } + + param = params.pop(); + } + } + + /** + * Find the relevant binding's scope. The owning scope is located by first + * inspecting the current scope and then moving "downward" through the stack + * of scopes. + * + * @param {string} bindingName - the value of the identifier + * + * @returns {Object} - the scope in which the binding was found + */ + function _getBinding(bindingName) { + for (var i = _scopeStack.length - 1 ; i >= 0; --i) { + var scopeBindings = _scopeStack[i]["(bindings)"]; + if (scopeBindings[bindingName]) { + return scopeBindings; + } + } + } + + /** + * Determine if a given binding name has been referenced within the current + * function or any function defined within. + * + * @param {string} bindingName - the value of the identifier + * + * @returns {boolean} + */ + function usedSoFarInCurrentFunction(bindingName) { + for (var i = _scopeStack.length - 1; i >= 0; i--) { + var current = _scopeStack[i]; + if (current["(usages)"][bindingName]) { + return current["(usages)"][bindingName]; + } + if (current === _currentFunctBody) { + break; + } + } + return false; + } + + function _checkOuterShadow(bindingName, token) { + + // only check if shadow is outer + if (state.option.shadow !== "outer") { + return; + } + + var isGlobal = _currentFunctBody["(type)"] === "global", + isNewFunction = _current["(type)"] === "functionparams"; + + var outsideCurrentFunction = !isGlobal; + for (var i = 0; i < _scopeStack.length; i++) { + var stackItem = _scopeStack[i]; + + if (!isNewFunction && _scopeStack[i + 1] === _currentFunctBody) { + outsideCurrentFunction = false; + } + if (outsideCurrentFunction && stackItem["(bindings)"][bindingName]) { + warning("W123", token, bindingName); + } + if (stackItem["(labels)"][bindingName]) { + warning("W123", token, bindingName); + } + } + } + + function _latedefWarning(type, bindingName, token) { + var isFunction; + + if (state.option.latedef) { + isFunction = type === "function" || type === "generator function" || + type === "async function"; + + // if either latedef is strict and this is a function + // or this is not a function + if ((state.option.latedef === true && isFunction) || !isFunction) { + warning("W003", token, bindingName); + } + } + } + + var scopeManagerInst = { + + on: function(names, listener) { + names.split(" ").forEach(function(name) { + emitter.on(name, listener); + }); + }, + + isPredefined: function(bindingName) { + return !this.has(bindingName) && _.has(_scopeStack[0]["(predefined)"], bindingName); + }, + + /** + * Create a new scope within the current scope. As the topmost value, the + * new scope will be interpreted as the current scope until it is + * exited--see the `unstack` method. + * + * @param {string} [type] - The type of the scope. Valid values are + * "functionparams", "catchparams" and + * "functionouter" + */ + stack: function(type) { + var previousScope = _current; + _newScope(type); + + if (!type && previousScope["(type)"] === "functionparams") { + + _current["(isFuncBody)"] = true; + _currentFunctBody = _current; + } + }, + + /** + * Valldate all binding references and declarations in the current scope + * and set the next scope on the stack as the active scope. + */ + unstack: function() { + // jshint proto: true + var subScope = _scopeStack.length > 1 ? _scopeStack[_scopeStack.length - 2] : null; + var isUnstackingFunctionBody = _current === _currentFunctBody, + isUnstackingFunctionParams = _current["(type)"] === "functionparams", + isUnstackingFunctionOuter = _current["(type)"] === "functionouter"; + + var i, j, isImmutable, isFunction; + var currentUsages = _current["(usages)"]; + var currentBindings = _current["(bindings)"]; + var usedBindingNameList = Object.keys(currentUsages); + + // See comment, "A note on `__proto__`" + /* istanbul ignore if */ + if (currentUsages.__proto__ && usedBindingNameList.indexOf("__proto__") === -1) { + usedBindingNameList.push("__proto__"); + } + + for (i = 0; i < usedBindingNameList.length; i++) { + var usedBindingName = usedBindingNameList[i]; + + var usage = currentUsages[usedBindingName]; + var usedBinding = currentBindings[usedBindingName]; + if (usedBinding) { + var usedBindingType = usedBinding["(type)"]; + isImmutable = usedBindingType === "const" || usedBindingType === "import"; + + if (usedBinding["(useOutsideOfScope)"] && !state.option.funcscope) { + var usedTokens = usage["(tokens)"]; + for (j = 0; j < usedTokens.length; j++) { + // Keep the consistency of https://github.com/jshint/jshint/issues/2409 + if (usedBinding["(function)"] === usedTokens[j]["(function)"]) { + error("W038", usedTokens[j], usedBindingName); + } + } + } + + // mark the binding used + _current["(bindings)"][usedBindingName]["(unused)"] = false; + + // check for modifying a const + if (isImmutable && usage["(modified)"]) { + for (j = 0; j < usage["(modified)"].length; j++) { + error("E013", usage["(modified)"][j], usedBindingName); + } + } + + isFunction = usedBindingType === "function" || + usedBindingType === "generator function" || + usedBindingType === "async function"; + + // check for re-assigning a function declaration + if ((isFunction || usedBindingType === "class") && usage["(reassigned)"]) { + for (j = 0; j < usage["(reassigned)"].length; j++) { + if (!usage["(reassigned)"][j].ignoreW021) { + warning("W021", usage["(reassigned)"][j], usedBindingName, usedBindingType); + } + } + } + continue; + } + + if (subScope) { + var bindingType = this.bindingtype(usedBindingName); + isImmutable = bindingType === "const" || + (bindingType === null && _scopeStack[0]["(predefined)"][usedBindingName] === false); + if (isUnstackingFunctionOuter && !isImmutable) { + if (!state.funct["(outerMutables)"]) { + state.funct["(outerMutables)"] = []; + } + state.funct["(outerMutables)"].push(usedBindingName); + } + + // not exiting the global scope, so copy the usage down in case its an out of scope usage + if (!subScope["(usages)"][usedBindingName]) { + subScope["(usages)"][usedBindingName] = usage; + if (isUnstackingFunctionBody) { + subScope["(usages)"][usedBindingName]["(onlyUsedSubFunction)"] = true; + } + } else { + var subScopeUsage = subScope["(usages)"][usedBindingName]; + subScopeUsage["(modified)"] = subScopeUsage["(modified)"].concat(usage["(modified)"]); + subScopeUsage["(tokens)"] = subScopeUsage["(tokens)"].concat(usage["(tokens)"]); + subScopeUsage["(reassigned)"] = + subScopeUsage["(reassigned)"].concat(usage["(reassigned)"]); + } + } else { + // this is exiting global scope, so we finalise everything here - we are at the end of the file + if (typeof _current["(predefined)"][usedBindingName] === "boolean") { + + // remove the declared token, so we know it is used + delete declared[usedBindingName]; + + // note it as used so it can be reported + usedPredefinedAndGlobals[usedBindingName] = marker; + + // check for re-assigning a read-only (set to false) predefined + if (_current["(predefined)"][usedBindingName] === false && usage["(reassigned)"]) { + for (j = 0; j < usage["(reassigned)"].length; j++) { + if (!usage["(reassigned)"][j].ignoreW020) { + warning("W020", usage["(reassigned)"][j]); + } + } + } + } + else { + // binding usage is not predefined and we have not found a declaration + // so report as undeclared + for (j = 0; j < usage["(tokens)"].length; j++) { + var undefinedToken = usage["(tokens)"][j]; + // if its not a forgiven undefined (e.g. typof x) + if (!undefinedToken.forgiveUndef) { + // if undef is on and undef was on when the token was defined + if (state.option.undef && !undefinedToken.ignoreUndef) { + warning("W117", undefinedToken, usedBindingName); + } + if (impliedGlobals[usedBindingName]) { + impliedGlobals[usedBindingName].line.push(undefinedToken.line); + } else { + impliedGlobals[usedBindingName] = { + name: usedBindingName, + line: [undefinedToken.line] + }; + } + } + } + } + } + } + + // if exiting the global scope, we can warn about declared globals that haven't been used yet + if (!subScope) { + Object.keys(declared) + .forEach(function(bindingNotUsed) { + _warnUnused(bindingNotUsed, declared[bindingNotUsed], "var"); + }); + } + + // If this is not a function boundary, transfer function-scoped bindings to + // the parent block (a rough simulation of variable hoisting). Previously + // existing bindings in the parent block should take precedence so that + // prior usages are not discarded. + if (subScope && !isUnstackingFunctionBody && + !isUnstackingFunctionParams && !isUnstackingFunctionOuter) { + var bindingNames = Object.keys(currentBindings); + for (i = 0; i < bindingNames.length; i++) { + + var defBindingName = bindingNames[i]; + var defBinding = currentBindings[defBindingName]; + + if (!defBinding["(blockscoped)"] && defBinding["(type)"] !== "exception") { + var shadowed = subScope["(bindings)"][defBindingName]; + + // Do not overwrite a binding if it exists in the parent scope + // because it is shared by adjacent blocks. Copy the `unused` + // property so that any references found within the current block + // are counted toward that higher-level declaration. + if (shadowed) { + shadowed["(unused)"] &= defBinding["(unused)"]; + + // "Hoist" the variable to the parent block, decorating the binding + // so that future references, though technically valid, can be + // reported as "out-of-scope" in the absence of the `funcscope` + // option. + } else { + defBinding["(useOutsideOfScope)"] = + // Do not warn about out-of-scope usages in the global scope + _currentFunctBody["(type)"] !== "global" && + // When a higher scope contains a binding for the binding, the + // binding is a re-declaration and should not prompt "used + // out-of-scope" warnings. + !this.funct.has(defBindingName, { excludeCurrent: true }); + + subScope["(bindings)"][defBindingName] = defBinding; + } + + delete currentBindings[defBindingName]; + } + } + } + + _checkForUnused(); + + _scopeStack.pop(); + if (isUnstackingFunctionBody) { + _currentFunctBody = _scopeStack[_.findLastIndex(_scopeStack, function(scope) { + // if function or if global (which is at the bottom so it will only return true if we call back) + return scope["(isFuncBody)"] || scope["(type)"] === "global"; + })]; + } + + _current = subScope; + }, + + /** + * Add a function parameter to the current scope. + * + * @param {string} bindingName - the value of the identifier + * @param {Token} token + * @param {string} [type] - binding type; defaults to "param" + */ + addParam: function(bindingName, token, type) { + type = type || "param"; + + if (type === "exception") { + // if defined in the current function + var previouslyDefinedBindingType = this.funct.bindingtype(bindingName); + if (previouslyDefinedBindingType && previouslyDefinedBindingType !== "exception") { + // and has not been used yet in the current function scope + if (!state.option.node) { + warning("W002", state.tokens.next, bindingName); + } + } + + if (state.isStrict() && (bindingName === "arguments" || bindingName === "eval")) { + warning("E008", token); + } + } + + // The variable was declared in the current scope + if (_.has(_current["(bindings)"], bindingName)) { + _current["(bindings)"][bindingName].duplicated = true; + + // The variable was declared in an outer scope + } else { + // if this scope has the variable defined, it's a re-definition error + _checkOuterShadow(bindingName, token); + + _current["(bindings)"][bindingName] = { + "(type)" : type, + "(token)": token, + "(unused)": true }; + + _current["(params)"].push(bindingName); + } + + if (_.has(_current["(usages)"], bindingName)) { + var usage = _current["(usages)"][bindingName]; + // if its in a sub function it is not necessarily an error, just latedef + if (usage["(onlyUsedSubFunction)"]) { + _latedefWarning(type, bindingName, token); + } else { + // this is a clear illegal usage, but not a syntax error, so emit a + // warning and not an error + warning("W003", token, bindingName); + } + } + }, + + validateParams: function(isArrow) { + var isStrict = state.isStrict(); + var currentFunctParamScope = _currentFunctBody["(parent)"]; + // From ECMAScript 2017: + // + // > 14.1.2Static Semantics: Early Errors + // > + // > [...] + // > - It is a Syntax Error if IsSimpleParameterList of + // > FormalParameterList is false and BoundNames of FormalParameterList + // > contains any duplicate elements. + var isSimple = state.funct['(hasSimpleParams)']; + // Method definitions are defined in terms of UniqueFormalParameters, so + // they cannot support duplicate parameter names regardless of strict + // mode. + var isMethod = state.funct["(method)"]; + + if (!currentFunctParamScope["(params)"]) { + /* istanbul ignore next */ + return; + } + + currentFunctParamScope["(params)"].forEach(function(bindingName) { + var binding = currentFunctParamScope["(bindings)"][bindingName]; + + if (binding.duplicated) { + if (isStrict || isArrow || isMethod || !isSimple) { + warning("E011", binding["(token)"], bindingName); + } else if (state.option.shadow !== true) { + warning("W004", binding["(token)"], bindingName); + } + } + + if (isStrict && (bindingName === "arguments" || bindingName === "eval")) { + warning("E008", binding["(token)"]); + } + }); + }, + + getUsedOrDefinedGlobals: function() { + // jshint proto: true + var list = Object.keys(usedPredefinedAndGlobals); + + // See comment, "A note on `__proto__`" + /* istanbul ignore if */ + if (usedPredefinedAndGlobals.__proto__ === marker && + list.indexOf("__proto__") === -1) { + list.push("__proto__"); + } + + return list; + }, + + /** + * Get an array of implied globals + * + * @returns {Array.<{ name: string, line: Array.}>} + */ + getImpliedGlobals: function() { + // jshint proto: true + var values = _.values(impliedGlobals); + var hasProto = false; + + // See comment, "A note on `__proto__`" + if (impliedGlobals.__proto__) { + hasProto = values.some(function(value) { + return value.name === "__proto__"; + }); + + /* istanbul ignore if */ + if (!hasProto) { + values.push(impliedGlobals.__proto__); + } + } + + return values; + }, + + /** + * Get an array of objects describing unused bindings. + * + * @returns {Array} + */ + getUnuseds: function() { + return unuseds; + }, + + /** + * Determine if a given name has been defined in the current scope or any + * lower scope. + * + * @param {string} bindingName - the value of the identifier + * + * @return {boolean} + */ + has: function(bindingName) { + return Boolean(_getBinding(bindingName)); + }, + + /** + * Retrieve binding described by `bindingName` or null + * + * @param {string} bindingName - the value of the identifier + * + * @returns {string|null} - the type of the binding or `null` if no such + * binding exists + */ + bindingtype: function(bindingName) { + var scopeBindings = _getBinding(bindingName); + if (scopeBindings) { + return scopeBindings[bindingName]["(type)"]; + } + return null; + }, + + /** + * For the exported options, indicating a variable is used outside the file + * + * @param {string} bindingName - the value of the identifier + */ + addExported: function(bindingName) { + var globalBindings = _scopeStack[0]["(bindings)"]; + if (_.has(declared, bindingName)) { + // remove the declared token, so we know it is used + delete declared[bindingName]; + } else if (_.has(globalBindings, bindingName)) { + globalBindings[bindingName]["(unused)"] = false; + } else { + for (var i = 1; i < _scopeStack.length; i++) { + var scope = _scopeStack[i]; + // if `scope.(type)` is not defined, it is a block scope + if (!scope["(type)"]) { + if (_.has(scope["(bindings)"], bindingName) && + !scope["(bindings)"][bindingName]["(blockscoped)"]) { + scope["(bindings)"][bindingName]["(unused)"] = false; + return; + } + } else { + break; + } + } + exported[bindingName] = true; + } + }, + + /** + * Mark a binding as "exported" by an ES2015 module + * + * @param {string} bindingName - the value of the identifier + * @param {object} token + */ + setExported: function(localName, exportName) { + if (exportName) { + if (esModuleExports.indexOf(exportName.value) > -1) { + error("E069", exportName, exportName.value); + } + + esModuleExports.push(exportName.value); + } + + if (localName) { + this.block.use(localName.value, localName); + } + }, + + /** + * Mark a binding as "initialized." This is necessary to enforce the + * "temporal dead zone" (TDZ) of block-scoped bindings which are not + * hoisted. + * + * @param {string} bindingName - the value of the identifier + */ + initialize: function(bindingName) { + if (_current["(bindings)"][bindingName]) { + _current["(bindings)"][bindingName]["(initialized)"] = true; + } + }, + + /** + * Create a new binding and add it to the current scope. Delegates to the + * internal `block.add` or `func.add` methods depending on the type. + * Produces warnings and errors as necessary. + * + * @param {string} bindingName + * @param {Object} opts + * @param {String} opts.type - the type of the binding e.g. "param", "var", + * "let, "const", "import", "function", + * "generator function", "async function", + * "async generator function" + * @param {object} opts.token - the token pointing at the declaration + * @param {boolean} opts.initialized - whether the binding should be + * created in an "initialized" state. + */ + addbinding: function(bindingName, opts) { + + var type = opts.type; + var token = opts.token; + var isblockscoped = type === "let" || type === "const" || + type === "class" || type === "import" || type === "generator function" || + type === "async function" || type === "async generator function"; + var ishoisted = type === "function" || type === "generator function" || + type === "async function" || type === "import"; + var isexported = (isblockscoped ? _current : _currentFunctBody)["(type)"] === "global" && + _.has(exported, bindingName); + + // outer shadow check (inner is only on non-block scoped) + _checkOuterShadow(bindingName, token); + + if (state.isStrict() && (bindingName === "arguments" || bindingName === "eval")) { + warning("E008", token); + } + + if (isblockscoped) { + + var declaredInCurrentScope = _current["(bindings)"][bindingName]; + // for block scoped variables, params are seen in the current scope as the root function + // scope, so check these too. + if (!declaredInCurrentScope && _current === _currentFunctBody && + _current["(type)"] !== "global") { + declaredInCurrentScope = !!_currentFunctBody["(parent)"]["(bindings)"][bindingName]; + } + + // if its not already defined (which is an error, so ignore) and is used in TDZ + if (!declaredInCurrentScope && _current["(usages)"][bindingName]) { + var usage = _current["(usages)"][bindingName]; + // if its in a sub function it is not necessarily an error, just latedef + if (usage["(onlyUsedSubFunction)"] || ishoisted) { + _latedefWarning(type, bindingName, token); + } else if (!ishoisted) { + // this is a clear illegal usage for block scoped variables + warning("E056", token, bindingName, type); + } + } + + // If this scope has already declared a binding with the same name, + // then this represents a redeclaration error if: + // + // 1. it is a "hoisted" block-scoped binding within a block. For + // instance: generator functions may be redeclared in the global + // scope but not within block statements + // 2. this is not a "hoisted" block-scoped binding + if (declaredInCurrentScope && + (!ishoisted || (_current["(type)"] !== "global" || type === "import"))) { + warning("E011", token, bindingName); + } + else if (state.option.shadow === "outer") { + + // if shadow is outer, for block scope we want to detect any shadowing within this function + if (scopeManagerInst.funct.has(bindingName)) { + warning("W004", token, bindingName); + } + } + + scopeManagerInst.block.add( + bindingName, type, token, !isexported, opts.initialized + ); + + } else { + + var declaredInCurrentFunctionScope = scopeManagerInst.funct.has(bindingName); + + // check for late definition, ignore if already declared + if (!declaredInCurrentFunctionScope && usedSoFarInCurrentFunction(bindingName)) { + _latedefWarning(type, bindingName, token); + } + + // defining with a var or a function when a block scope variable of the same name + // is in scope is an error + if (scopeManagerInst.funct.has(bindingName, { onlyBlockscoped: true })) { + warning("E011", token, bindingName); + } else if (state.option.shadow !== true) { + // now since we didn't get any block scope variables, test for var/function + // shadowing + if (declaredInCurrentFunctionScope && bindingName !== "__proto__") { + + // see https://github.com/jshint/jshint/issues/2400 + if (_currentFunctBody["(type)"] !== "global") { + warning("W004", token, bindingName); + } + } + } + + scopeManagerInst.funct.add(bindingName, type, token, !isexported); + + if (_currentFunctBody["(type)"] === "global" && !state.impliedClosure()) { + usedPredefinedAndGlobals[bindingName] = marker; + } + } + }, + + funct: { + /** + * Return the type of the provided binding given certain options + * + * @param {string} bindingName + * @param {Object=} [options] + * @param {boolean} [options.onlyBlockscoped] - only include block scoped + * bindings + * @param {boolean} [options.excludeParams] - exclude the param scope + * @param {boolean} [options.excludeCurrent] - exclude the current scope + * + * @returns {String} + */ + bindingtype: function(bindingName, options) { + var onlyBlockscoped = options && options.onlyBlockscoped; + var excludeParams = options && options.excludeParams; + var currentScopeIndex = _scopeStack.length - (options && options.excludeCurrent ? 2 : 1); + for (var i = currentScopeIndex; i >= 0; i--) { + var current = _scopeStack[i]; + if (current["(bindings)"][bindingName] && + (!onlyBlockscoped || current["(bindings)"][bindingName]["(blockscoped)"])) { + return current["(bindings)"][bindingName]["(type)"]; + } + var scopeCheck = excludeParams ? _scopeStack[ i - 1 ] : current; + if (scopeCheck && scopeCheck["(type)"] === "functionparams") { + return null; + } + } + return null; + }, + + /** + * Determine whether a `break` statement label exists in the function + * scope. + * + * @param {string} labelName - the value of the identifier + * + * @returns {boolean} + */ + hasLabel: function(labelName) { + for (var i = _scopeStack.length - 1; i >= 0; i--) { + var current = _scopeStack[i]; + + if (current["(labels)"][labelName]) { + return true; + } + if (current["(type)"] === "functionparams") { + return false; + } + } + return false; + }, + + /** + * Determine if a given name has been defined in the current function + * scope. + * + * @param {string} bindingName - the value of the identifier + * @param {object} options - options as supported by the + * `funct.bindingtype` method + * + * @return {boolean} + */ + has: function(bindingName, options) { + return Boolean(this.bindingtype(bindingName, options)); + }, + + /** + * Create a new function-scoped binding and add it to the current scope. + * See the `block.add` method for coresponding logic to create + * block-scoped bindings. + * + * @param {string} bindingName - the value of the identifier + * @param {string} type - the type of the binding; either "function" or + * "var" + * @param {object} tok - the token that triggered the definition + * @param {boolean} unused - `true` if the binding has not been + * referenced + */ + add: function(bindingName, type, tok, unused) { + _current["(bindings)"][bindingName] = { + "(type)" : type, + "(token)": tok, + "(blockscoped)": false, + "(function)": _currentFunctBody, + "(unused)": unused }; + } + }, + + block: { + + /** + * Determine whether the current block scope is the global scope. + * + * @returns Boolean + */ + isGlobal: function() { + return _current["(type)"] === "global"; + }, + + /** + * Resolve a reference to a binding and mark the corresponding binding as + * "used." + * + * @param {string} bindingName - the value of the identifier + * @param {object} token - the token value that triggered the reference + */ + use: function(bindingName, token) { + // If the name resolves to a parameter of the current function, then do + // not store usage. This is because in cases such as the following: + // + // function(a) { + // var a; + // a = a; + // } + // + // the usage of `a` will resolve to the parameter, not to the unset + // variable binding. + var paramScope = _currentFunctBody["(parent)"]; + if (paramScope && paramScope["(bindings)"][bindingName] && + paramScope["(bindings)"][bindingName]["(type)"] === "param") { + + // then check its not declared by a block scope variable + if (!scopeManagerInst.funct.has(bindingName, + { excludeParams: true, onlyBlockscoped: true })) { + paramScope["(bindings)"][bindingName]["(unused)"] = false; + } + } + + if (token && (state.ignored.W117 || state.option.undef === false)) { + token.ignoreUndef = true; + } + + _setupUsages(bindingName); + + _current["(usages)"][bindingName]["(onlyUsedSubFunction)"] = false; + + if (token) { + token["(function)"] = _currentFunctBody; + _current["(usages)"][bindingName]["(tokens)"].push(token); + } + + // Block-scoped bindings can't be used within their initializer due to + // "temporal dead zone" (TDZ) restrictions. + var binding = _current["(bindings)"][bindingName]; + if (binding && binding["(blockscoped)"] && !binding["(initialized)"]) { + error("E056", token, bindingName, binding["(type)"]); + } + }, + + reassign: function(bindingName, token) { + token.ignoreW020 = state.ignored.W020; + token.ignoreW021 = state.ignored.W021; + + this.modify(bindingName, token); + + _current["(usages)"][bindingName]["(reassigned)"].push(token); + }, + + modify: function(bindingName, token) { + + _setupUsages(bindingName); + + _current["(usages)"][bindingName]["(onlyUsedSubFunction)"] = false; + _current["(usages)"][bindingName]["(modified)"].push(token); + }, + + /** + * Create a new block-scoped binding and add it to the current scope. See + * the `funct.add` method for coresponding logic to create + * function-scoped bindings. + * + * @param {string} bindingName - the value of the identifier + * @param {string} type - the type of the binding; one of "class", + * "const", "function", "import", or "let" + * @param {object} tok - the token that triggered the definition + * @param {boolean} unused - `true` if the binding has not been + * referenced + * @param {boolean} initialized - `true` if the binding has been + * initialized (as is the case with + * bindings created via `import` + * declarations) + */ + add: function(bindingName, type, tok, unused, initialized) { + _current["(bindings)"][bindingName] = { + "(type)" : type, + "(token)": tok, + "(initialized)": !!initialized, + "(blockscoped)": true, + "(unused)": unused }; + }, + + addLabel: function(labelName, opts) { + var token = opts.token; + if (scopeManagerInst.funct.hasLabel(labelName)) { + warning("E011", token, labelName); + } + else if (state.option.shadow === "outer") { + if (scopeManagerInst.funct.has(labelName)) { + warning("W004", token, labelName); + } else { + _checkOuterShadow(labelName, token); + } + } + _current["(labels)"][labelName] = token; + } + } + }; + return scopeManagerInst; +}; + +module.exports = scopeManager; + +},{"events":"/node_modules/events/events.js","lodash.slice":"/../../../jshint/node_modules/lodash.slice/index.js","underscore":"/../../../jshint/node_modules/underscore/underscore-umd.js"}],"/../../../jshint/src/state.js":[function(_dereq_,module,exports){ +"use strict"; +var NameStack = _dereq_("./name-stack.js"); + +var state = { + syntax: {}, + + /** + * Determine if the code currently being linted is strict mode code. + * + * @returns {boolean} + */ + isStrict: function() { + return !!this.directive["use strict"] || this.inClassBody || + this.option.module || this.option.strict === "implied"; + }, + + /** + * Determine if the current state warrants a warning for statements outside + * of strict mode code. + * + * While emitting warnings based on function scope would be more intuitive + * (and less noisy), JSHint observes statement-based semantics in order to + * preserve legacy behavior. + * + * This method does not take the state of the parser into account, making no + * distinction between global code and function code. Because the "missing + * 'use strict'" warning is *also* reported at function boundaries, this + * function interprets `strict` option values `true` and `undefined` as + * equivalent. + */ + stmtMissingStrict: function() { + if (this.option.strict === "global") { + return true; + } + + if (this.option.strict === false) { + return false; + } + + if (this.option.globalstrict) { + return true; + } + + return false; + }, + + allowsGlobalUsd: function() { + return this.option.strict === "global" || this.option.globalstrict || + this.option.module || this.impliedClosure(); + }, + + /** + * Determine if the current configuration describes an environment that is + * wrapped in an immediately-invoked function expression prior to evaluation. + * + * @returns {boolean} + */ + impliedClosure: function() { + return this.option.node || this.option.phantom || this.option.browserify; + }, + + // Assumption: chronologically ES3 < ES5 < ES6 < Moz + + inMoz: function() { + return this.option.moz; + }, + + /** + * Determine if constructs introduced in ECMAScript 11 should be accepted. + * + * @returns {boolean} + */ + inES11: function() { + return this.esVersion >= 11; + }, + + /** + * Determine if constructs introduced in ECMAScript 10 should be accepted. + * + * @returns {boolean} + */ + inES10: function() { + return this.esVersion >= 10; + }, + + /** + * Determine if constructs introduced in ECMAScript 9 should be accepted. + * + * @returns {boolean} + */ + inES9: function() { + return this.esVersion >= 9; + }, + + /** + * Determine if constructs introduced in ECMAScript 8 should be accepted. + * + * @returns {boolean} + */ + inES8: function() { + return this.esVersion >= 8; + }, + + /** + * Determine if constructs introduced in ECMAScript 7 should be accepted. + * + * @returns {boolean} + */ + inES7: function() { + return this.esVersion >= 7; + }, + + /** + * Determine if constructs introduced in ECMAScript 6 should be accepted. + * + * @param {boolean} strict - When `true`, do not interpret the `moz` option + * as ECMAScript 6 + * + * @returns {boolean} + */ + inES6: function(strict) { + if (!strict && this.option.moz) { + return true; + } + + return this.esVersion >= 6; + }, + + /** + * Determine if constructs introduced in ECMAScript 5 should be accepted. + * + * @returns {boolean} + */ + inES5: function() { + return !this.esVersion || this.esVersion >= 5 || this.option.moz; + }, + + /** + * Determine the current version of the input language by inspecting the + * value of all ECMAScript-version-related options. This logic is necessary + * to ensure compatibility with deprecated options `es3`, `es5`, and + * `esnext`, and it may be drastically simplified when those options are + * removed. + * + * @returns {string|null} - the name of any incompatible option detected, + * `null` otherwise + */ + inferEsVersion: function() { + var badOpt = null; + + if (this.option.esversion) { + if (this.option.es3) { + badOpt = "es3"; + } else if (this.option.es5) { + badOpt = "es5"; + } else if (this.option.esnext) { + badOpt = "esnext"; + } + + if (badOpt) { + return badOpt; + } + + if (this.option.esversion === 2015) { + this.esVersion = 6; + } else { + this.esVersion = this.option.esversion; + } + } else if (this.option.es3) { + this.esVersion = 3; + } else if (this.option.esnext) { + this.esVersion = 6; + } + + return null; + }, + + reset: function() { + this.tokens = { + prev: null, + next: null, + curr: null + }; + + this.option = { unstable: {} }; + this.esVersion = 5; + this.funct = null; + this.ignored = {}; + /** + * A lookup table for active directives whose keys are the value of the + * directives and whose values are the tokens which enabled the directives. + */ + this.directive = Object.create(null); + this.jsonMode = false; + this.lines = []; + this.tab = ""; + this.cache = {}; // Node.JS doesn't have Map. Sniff. + this.ignoredLines = {}; + this.forinifcheckneeded = false; + this.nameStack = new NameStack(); + this.inClassBody = false; + } +}; + +exports.state = state; + +},{"./name-stack.js":"/../../../jshint/src/name-stack.js"}],"/../../../jshint/src/style.js":[function(_dereq_,module,exports){ +"use strict"; + +exports.register = function(linter) { + // Check for properties named __proto__. This special property was + // deprecated and then re-introduced for ES6. + + linter.on("Identifier", function style_scanProto(data) { + if (linter.getOption("proto")) { + return; + } + + if (data.name === "__proto__") { + linter.warn("W103", { + line: data.line, + char: data.char, + data: [ data.name, "6" ] + }); + } + }); + + // Check for properties named __iterator__. This is a special property + // available only in browsers with JavaScript 1.7 implementation, but + // it is deprecated for ES6 + + linter.on("Identifier", function style_scanIterator(data) { + if (linter.getOption("iterator")) { + return; + } + + if (data.name === "__iterator__") { + linter.warn("W103", { + line: data.line, + char: data.char, + data: [ data.name ] + }); + } + }); + + // Check that all identifiers are using camelCase notation. + // Exceptions: names like MY_VAR and _myVar. + + linter.on("Identifier", function style_scanCamelCase(data) { + if (!linter.getOption("camelcase")) { + return; + } + + if (data.name.replace(/^_+|_+$/g, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) { + linter.warn("W106", { + line: data.line, + char: data.char, + data: [ data.name ] + }); + } + }); + + // Enforce consistency in style of quoting. + + linter.on("String", function style_scanQuotes(data) { + var quotmark = linter.getOption("quotmark"); + var code; + + if (!quotmark) { + return; + } + + // If quotmark is set to 'single' warn about all double-quotes. + + if (quotmark === "single" && data.quote !== "'") { + code = "W109"; + } + + // If quotmark is set to 'double' warn about all single-quotes. + + if (quotmark === "double" && data.quote !== "\"") { + code = "W108"; + } + + // If quotmark is set to true, remember the first quotation style + // and then warn about all others. + + if (quotmark === true) { + if (!linter.getCache("quotmark")) { + linter.setCache("quotmark", data.quote); + } + + if (linter.getCache("quotmark") !== data.quote) { + code = "W110"; + } + } + + if (code) { + linter.warn(code, { + line: data.line, + char: data.char, + }); + } + }); + + linter.on("Number", function style_scanNumbers(data) { + if (data.value.charAt(0) === ".") { + // Warn about a leading decimal point. + linter.warn("W008", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } + + if (data.value.substr(data.value.length - 1) === ".") { + // Warn about a trailing decimal point. + linter.warn("W047", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } + + if (/^00+/.test(data.value)) { + // Multiple leading zeroes. + linter.warn("W046", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } + }); + + // Warn about script URLs. + + linter.on("String", function style_scanJavaScriptURLs(data) { + var re = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i; + + if (linter.getOption("scripturl")) { + return; + } + + if (re.test(data.value)) { + linter.warn("W107", { + line: data.line, + char: data.char + }); + } + }); +}; + +},{}],"/../../../jshint/src/validate-unicode-escape-sequence.js":[function(_dereq_,module,exports){ +/* + * Determine whether a given string is a valid UnicodePropertyValueExpression. + */ + +"use strict"; + +module.exports = function validate(sequence) { + var equalSignIndex = sequence.indexOf("="); + + if (equalSignIndex === -1) { + return sequence in names.binary || sequence in values.general; + } + + var name = sequence.substr(0, equalSignIndex); + var value = sequence.substr(equalSignIndex + 1); + + if (name === "General_Category" || name === "gc") { + return value in values.general; + } if (name === "Script" || name === "sc" || name === "Script_Extensions" || name === "scx") { + return value in values.script; + } + + return false; +}; + + +var names = { + nonBinary: Object.create(null), + binary: Object.create(null) +}; +var values = { + general: Object.create(null), + script: Object.create(null) +}; + +var nb = names.nonBinary; +nb.General_Category = true; +nb.gc = true; +nb.Script = true; +nb.sc = true; +nb.Script_Extensions = true; +nb.scx = true; + +var b = names.binary; +b.ASCII = true; +b.ASCII_Hex_Digit = true; +b.AHex = true; +b.Alphabetic = true; +b.Alpha = true; +b.Any = true; +b.Assigned = true; +b.Bidi_Control = true; +b.Bidi_C = true; +b.Bidi_Mirrored = true; +b.Bidi_M = true; +b.Case_Ignorable = true; +b.CI = true; +b.Cased = true; +b.Changes_When_Casefolded = true; +b.CWCF = true; +b.Changes_When_Casemapped = true; +b.CWCM = true; +b.Changes_When_Lowercased = true; +b.CWL = true; +b.Changes_When_NFKC_Casefolded = true; +b.CWKCF = true; +b.Changes_When_Titlecased = true; +b.CWT = true; +b.Changes_When_Uppercased = true; +b.CWU = true; +b.Dash = true; +b.Default_Ignorable_Code_Point = true; +b.DI = true; +b.Deprecated = true; +b.Dep = true; +b.Diacritic = true; +b.Dia = true; +b.Emoji = true; +b.Emoji_Component = true; +b.EComp = true; +b.Emoji_Modifier = true; +b.EMod = true; +b.Emoji_Modifier_Base = true; +b.EBase = true; +b.Emoji_Presentation = true; +b.EPres = true; +b.Extended_Pictographic = true; +b.ExtPict = true; +b.Extender = true; +b.Ext = true; +b.Grapheme_Base = true; +b.Gr_Base = true; +b.Grapheme_Extend = true; +b.Gr_Ext = true; +b.Hex_Digit = true; +b.Hex = true; +b.IDS_Binary_Operator = true; +b.IDSB = true; +b.IDS_Trinary_Operator = true; +b.IDST = true; +b.ID_Continue = true; +b.IDC = true; +b.ID_Start = true; +b.IDS = true; +b.Ideographic = true; +b.Ideo = true; +b.Join_Control = true; +b.Join_C = true; +b.Logical_Order_Exception = true; +b.LOE = true; +b.Lowercase = true; +b.Lower = true; +b.Math = true; +b.Noncharacter_Code_Point = true; +b.NChar = true; +b.Pattern_Syntax = true; +b.Pat_Syn = true; +b.Pattern_White_Space = true; +b.Pat_WS = true; +b.Quotation_Mark = true; +b.QMark = true; +b.Radical = true; +b.Regional_Indicator = true; +b.RI = true; +b.Sentence_Terminal = true; +b.STerm = true; +b.Soft_Dotted = true; +b.SD = true; +b.Terminal_Punctuation = true; +b.Term = true; +b.Unified_Ideograph = true; +b.UIdeo = true; +b.Uppercase = true; +b.Upper = true; +b.Variation_Selector = true; +b.VS = true; +b.White_Space = true; +b.space = true; +b.XID_Continue = true; +b.XIDC = true; +b.XID_Start = true; +b.XIDS = true; + +var g = values.general; +g.Cased_Letter = true; +g.LC = true; +g.Close_Punctuation = true; +g.Pe = true; +g.Connector_Punctuation = true; +g.Pc = true; +g.Control = true; +g.Cc = true; +g.cntrl = true; +g.Currency_Symbol = true; +g.Sc = true; +g.Dash_Punctuation = true; +g.Pd = true; +g.Decimal_Number = true; +g.Nd = true; +g.digit = true; +g.Enclosing_Mark = true; +g.Me = true; +g.Final_Punctuation = true; +g.Pf = true; +g.Format = true; +g.Cf = true; +g.Initial_Punctuation = true; +g.Pi = true; +g.Letter = true; +g.L = true; +g.Letter_Number = true; +g.Nl = true; +g.Line_Separator = true; +g.Zl = true; +g.Lowercase_Letter = true; +g.Ll = true; +g.Mark = true; +g.M = true; +g.Combining_Mark = true; +g.Math_Symbol = true; +g.Sm = true; +g.Modifier_Letter = true; +g.Lm = true; +g.Modifier_Symbol = true; +g.Sk = true; +g.Nonspacing_Mark = true; +g.Mn = true; +g.Number = true; +g.N = true; +g.Open_Punctuation = true; +g.Ps = true; +g.Other = true; +g.C = true; +g.Other_Letter = true; +g.Lo = true; +g.Other_Number = true; +g.No = true; +g.Other_Punctuation = true; +g.Po = true; +g.Other_Symbol = true; +g.So = true; +g.Paragraph_Separator = true; +g.Zp = true; +g.Private_Use = true; +g.Co = true; +g.Punctuation = true; +g.P = true; +g.punct = true; +g.Separator = true; +g.Z = true; +g.Space_Separator = true; +g.Zs = true; +g.Spacing_Mark = true; +g.Mc = true; +g.Surrogate = true; +g.Cs = true; +g.Symbol = true; +g.S = true; +g.Titlecase_Letter = true; +g.Lt = true; +g.Unassigned = true; +g.Cn = true; +g.Uppercase_Letter = true; +g.Lu = true; + +var s = values.script; +s.Adlam = true; +s.Adlm = true; +s.Ahom = true; +s.Anatolian_Hieroglyphs = true; +s.Hluw = true; +s.Arabic = true; +s.Arab = true; +s.Armenian = true; +s.Armn = true; +s.Avestan = true; +s.Avst = true; +s.Balinese = true; +s.Bali = true; +s.Bamum = true; +s.Bamu = true; +s.Bassa_Vah = true; +s.Bass = true; +s.Batak = true; +s.Batk = true; +s.Bengali = true; +s.Beng = true; +s.Bhaiksuki = true; +s.Bhks = true; +s.Bopomofo = true; +s.Bopo = true; +s.Brahmi = true; +s.Brah = true; +s.Braille = true; +s.Brai = true; +s.Buginese = true; +s.Bugi = true; +s.Buhid = true; +s.Buhd = true; +s.Canadian_Aboriginal = true; +s.Cans = true; +s.Carian = true; +s.Cari = true; +s.Caucasian_Albanian = true; +s.Aghb = true; +s.Chakma = true; +s.Cakm = true; +s.Cham = true; +s.Chorasmian = true; +s.Chrs = true; +s.Cherokee = true; +s.Cher = true; +s.Common = true; +s.Zyyy = true; +s.Coptic = true; +s.Copt = true; +s.Qaac = true; +s.Cuneiform = true; +s.Xsux = true; +s.Cypriot = true; +s.Cprt = true; +s.Cyrillic = true; +s.Cyrl = true; +s.Deseret = true; +s.Dsrt = true; +s.Devanagari = true; +s.Deva = true; +s.Dives_Akuru = true; +s.Diak = true; +s.Dogra = true; +s.Dogr = true; +s.Duployan = true; +s.Dupl = true; +s.Egyptian_Hieroglyphs = true; +s.Egyp = true; +s.Elbasan = true; +s.Elba = true; +s.Elymaic = true; +s.Elym = true; +s.Ethiopic = true; +s.Ethi = true; +s.Georgian = true; +s.Geor = true; +s.Glagolitic = true; +s.Glag = true; +s.Gothic = true; +s.Goth = true; +s.Grantha = true; +s.Gran = true; +s.Greek = true; +s.Grek = true; +s.Gujarati = true; +s.Gujr = true; +s.Gunjala_Gondi = true; +s.Gong = true; +s.Gurmukhi = true; +s.Guru = true; +s.Han = true; +s.Hani = true; +s.Hangul = true; +s.Hang = true; +s.Hanifi_Rohingya = true; +s.Rohg = true; +s.Hanunoo = true; +s.Hano = true; +s.Hatran = true; +s.Hatr = true; +s.Hebrew = true; +s.Hebr = true; +s.Hiragana = true; +s.Hira = true; +s.Imperial_Aramaic = true; +s.Armi = true; +s.Inherited = true; +s.Zinh = true; +s.Qaai = true; +s.Inscriptional_Pahlavi = true; +s.Phli = true; +s.Inscriptional_Parthian = true; +s.Prti = true; +s.Javanese = true; +s.Java = true; +s.Kaithi = true; +s.Kthi = true; +s.Kannada = true; +s.Knda = true; +s.Katakana = true; +s.Kana = true; +s.Kayah_Li = true; +s.Kali = true; +s.Kharoshthi = true; +s.Khar = true; +s.Khitan_Small_Script = true; +s.Kits = true; +s.Khmer = true; +s.Khmr = true; +s.Khojki = true; +s.Khoj = true; +s.Khudawadi = true; +s.Sind = true; +s.Lao = true; +s.Laoo = true; +s.Latin = true; +s.Latn = true; +s.Lepcha = true; +s.Lepc = true; +s.Limbu = true; +s.Limb = true; +s.Linear_A = true; +s.Lina = true; +s.Linear_B = true; +s.Linb = true; +s.Lisu = true; +s.Lycian = true; +s.Lyci = true; +s.Lydian = true; +s.Lydi = true; +s.Mahajani = true; +s.Mahj = true; +s.Makasar = true; +s.Maka = true; +s.Malayalam = true; +s.Mlym = true; +s.Mandaic = true; +s.Mand = true; +s.Manichaean = true; +s.Mani = true; +s.Marchen = true; +s.Marc = true; +s.Medefaidrin = true; +s.Medf = true; +s.Masaram_Gondi = true; +s.Gonm = true; +s.Meetei_Mayek = true; +s.Mtei = true; +s.Mende_Kikakui = true; +s.Mend = true; +s.Meroitic_Cursive = true; +s.Merc = true; +s.Meroitic_Hieroglyphs = true; +s.Mero = true; +s.Miao = true; +s.Plrd = true; +s.Modi = true; +s.Mongolian = true; +s.Mong = true; +s.Mro = true; +s.Mroo = true; +s.Multani = true; +s.Mult = true; +s.Myanmar = true; +s.Mymr = true; +s.Nabataean = true; +s.Nbat = true; +s.Nandinagari = true; +s.Nand = true; +s.New_Tai_Lue = true; +s.Talu = true; +s.Newa = true; +s.Nko = true; +s.Nkoo = true; +s.Nushu = true; +s.Nshu = true; +s.Nyiakeng_Puachue_Hmong = true; +s.Hmnp = true; +s.Ogham = true; +s.Ogam = true; +s.Ol_Chiki = true; +s.Olck = true; +s.Old_Hungarian = true; +s.Hung = true; +s.Old_Italic = true; +s.Ital = true; +s.Old_North_Arabian = true; +s.Narb = true; +s.Old_Permic = true; +s.Perm = true; +s.Old_Persian = true; +s.Xpeo = true; +s.Old_Sogdian = true; +s.Sogo = true; +s.Old_South_Arabian = true; +s.Sarb = true; +s.Old_Turkic = true; +s.Orkh = true; +s.Oriya = true; +s.Orya = true; +s.Osage = true; +s.Osge = true; +s.Osmanya = true; +s.Osma = true; +s.Pahawh_Hmong = true; +s.Hmng = true; +s.Palmyrene = true; +s.Palm = true; +s.Pau_Cin_Hau = true; +s.Pauc = true; +s.Phags_Pa = true; +s.Phag = true; +s.Phoenician = true; +s.Phnx = true; +s.Psalter_Pahlavi = true; +s.Phlp = true; +s.Rejang = true; +s.Rjng = true; +s.Runic = true; +s.Runr = true; +s.Samaritan = true; +s.Samr = true; +s.Saurashtra = true; +s.Saur = true; +s.Sharada = true; +s.Shrd = true; +s.Shavian = true; +s.Shaw = true; +s.Siddham = true; +s.Sidd = true; +s.SignWriting = true; +s.Sgnw = true; +s.Sinhala = true; +s.Sinh = true; +s.Sogdian = true; +s.Sogd = true; +s.Sora_Sompeng = true; +s.Sora = true; +s.Soyombo = true; +s.Soyo = true; +s.Sundanese = true; +s.Sund = true; +s.Syloti_Nagri = true; +s.Sylo = true; +s.Syriac = true; +s.Syrc = true; +s.Tagalog = true; +s.Tglg = true; +s.Tagbanwa = true; +s.Tagb = true; +s.Tai_Le = true; +s.Tale = true; +s.Tai_Tham = true; +s.Lana = true; +s.Tai_Viet = true; +s.Tavt = true; +s.Takri = true; +s.Takr = true; +s.Tamil = true; +s.Taml = true; +s.Tangut = true; +s.Tang = true; +s.Telugu = true; +s.Telu = true; +s.Thaana = true; +s.Thaa = true; +s.Thai = true; +s.Tibetan = true; +s.Tibt = true; +s.Tifinagh = true; +s.Tfng = true; +s.Tirhuta = true; +s.Tirh = true; +s.Ugaritic = true; +s.Ugar = true; +s.Vai = true; +s.Vaii = true; +s.Wancho = true; +s.Wcho = true; +s.Warang_Citi = true; +s.Wara = true; +s.Yezidi = true; +s.Yezi = true; +s.Yi = true; +s.Yiii = true; +s.Zanabazar_Square = true; +s.Zanb = true; + +},{}],"/../../../jshint/src/vars.js":[function(_dereq_,module,exports){ +// jshint -W001 + +"use strict"; + +// Identifiers provided by the ECMAScript standard. + +exports.reservedVars = { + NaN : false, + undefined : false +}; + +exports.ecmaIdentifiers = { + 3: { + Array : false, + Boolean : false, + Date : false, + decodeURI : false, + decodeURIComponent : false, + encodeURI : false, + encodeURIComponent : false, + Error : false, + "eval" : false, + EvalError : false, + Function : false, + hasOwnProperty : false, + Infinity : false, + isFinite : false, + isNaN : false, + Math : false, + Number : false, + Object : false, + parseInt : false, + parseFloat : false, + RangeError : false, + ReferenceError : false, + RegExp : false, + String : false, + SyntaxError : false, + TypeError : false, + URIError : false + }, + 5: { + JSON : false + }, + 6: { + ArrayBuffer : false, + DataView : false, + Float32Array : false, + Float64Array : false, + Int8Array : false, + Int16Array : false, + Int32Array : false, + Map : false, + Promise : false, + Proxy : false, + Reflect : false, + Set : false, + Symbol : false, + Uint8Array : false, + Uint16Array : false, + Uint32Array : false, + Uint8ClampedArray : false, + WeakMap : false, + WeakSet : false + }, + 8: { + Atomics : false, + SharedArrayBuffer : false + }, + 11: { + BigInt : false, + globalThis : false + } +}; + +// Global variables commonly provided by a web browser environment. + +exports.browser = { + Audio : false, Blob : false, - addEventListener : false, + addEventListener : false, // EventTarget applicationCache : false, - atob : false, + atob : false, // WindowOrWorkerGlobalScope blur : false, - btoa : false, + btoa : false, // WindowOrWorkerGlobalScope cancelAnimationFrame : false, CanvasGradient : false, CanvasPattern : false, CanvasRenderingContext2D: false, CSS : false, - clearInterval : false, - clearTimeout : false, + CSSImportRule : false, + CSSGroupingRule : false, + CSSMarginRule : false, + CSSMediaRule : false, + CSSNamespaceRule : false, + CSSPageRule : false, + CSSRule : false, + CSSRuleList : false, + CSSStyleDeclaration : false, + CSSStyleRule : false, + CSSStyleSheet : false, + clearInterval : false, // WindowOrWorkerGlobalScope + clearTimeout : false, // WindowOrWorkerGlobalScope close : false, closed : false, Comment : false, + CompositionEvent : false, + createImageBitmap : false, // WindowOrWorkerGlobalScope CustomEvent : false, DOMParser : false, defaultStatus : false, + dispatchEvent : false, // EventTarget Document : false, document : false, DocumentFragment : false, @@ -11734,13 +17103,17 @@ exports.browser = { Event : false, event : false, fetch : false, + File : false, + FileList : false, FileReader : false, FormData : false, focus : false, frames : false, getComputedStyle : false, - HTMLElement : false, + Headers : false, HTMLAnchorElement : false, + HTMLAreaElement : false, + HTMLAudioElement : false, HTMLBaseElement : false, HTMLBlockquoteElement: false, HTMLBodyElement : false, @@ -11748,9 +17121,15 @@ exports.browser = { HTMLButtonElement : false, HTMLCanvasElement : false, HTMLCollection : false, + HTMLDataElement : false, + HTMLDataListElement : false, + HTMLDetailsElement : false, + HTMLDialogElement : false, HTMLDirectoryElement : false, HTMLDivElement : false, HTMLDListElement : false, + HTMLElement : false, + HTMLEmbedElement : false, HTMLFieldSetElement : false, HTMLFontElement : false, HTMLFormElement : false, @@ -11763,6 +17142,13 @@ exports.browser = { HTMLIFrameElement : false, HTMLImageElement : false, HTMLInputElement : false, +/* HTMLIsIndexElement was removed from the WHATWG HTML spec; + see https://github.com/whatwg/html/pull/1095. + HTMLIsIndexElement has been removed from browsers; see: + • Chromium Removal: https://codereview.chromium.org/96653004/ + • Gecko Removal: https://bugzilla.mozilla.org/show_bug.cgi?id=1266495 + • WebKit Removal: https://bugs.webkit.org/show_bug.cgi?id=7139. + See also the discussion at https://github.com/jshint/jshint/pull/3222. */ HTMLIsIndexElement : false, HTMLLabelElement : false, HTMLLayerElement : false, @@ -11770,8 +17156,11 @@ exports.browser = { HTMLLIElement : false, HTMLLinkElement : false, HTMLMapElement : false, + HTMLMarqueeElement : false, + HTMLMediaElement : false, HTMLMenuElement : false, HTMLMetaElement : false, + HTMLMeterElement : false, HTMLModElement : false, HTMLObjectElement : false, HTMLOListElement : false, @@ -11779,10 +17168,14 @@ exports.browser = { HTMLOptionElement : false, HTMLParagraphElement : false, HTMLParamElement : false, + HTMLPictureElement : false, HTMLPreElement : false, + HTMLProgressElement : false, HTMLQuoteElement : false, HTMLScriptElement : false, HTMLSelectElement : false, + HTMLSlotElement : false, + HTMLSourceElement : false, HTMLStyleElement : false, HTMLTableCaptionElement: false, HTMLTableCellElement : false, @@ -11792,16 +17185,21 @@ exports.browser = { HTMLTableSectionElement: false, HTMLTemplateElement : false, HTMLTextAreaElement : false, + HTMLTimeElement : false, HTMLTitleElement : false, + HTMLTrackElement : false, HTMLUListElement : false, HTMLVideoElement : false, history : false, Image : false, + IntersectionObserver : false, Intl : false, length : false, localStorage : false, location : false, matchMedia : false, + MediaList : false, + MediaRecorder : false, MessageChannel : false, MessageEvent : false, MessagePort : false, @@ -11826,23 +17224,29 @@ exports.browser = { openDatabase : false, opener : false, Option : false, + origin : false, // WindowOrWorkerGlobalScope parent : false, performance : false, print : false, + queueMicrotask : false, // WindowOrWorkerGlobalScope Range : false, requestAnimationFrame : false, - removeEventListener : false, + removeEventListener : false, // EventTarget + Request : false, resizeBy : false, resizeTo : false, + Response : false, screen : false, scroll : false, scrollBy : false, scrollTo : false, sessionStorage : false, - setInterval : false, - setTimeout : false, + setInterval : false, // WindowOrWorkerGlobalScope + setTimeout : false, // WindowOrWorkerGlobalScope SharedWorker : false, status : false, + Storage : false, + StyleSheet : false, SVGAElement : false, SVGAltGlyphDefElement: false, SVGAltGlyphElement : false, @@ -12004,6 +17408,7 @@ exports.browser = { TimeEvent : false, top : false, URL : false, + URLSearchParams : false, WebGLActiveInfo : false, WebGLBuffer : false, WebGLContextEvent : false, @@ -12020,6 +17425,7 @@ exports.browser = { Window : false, Worker : false, XDomainRequest : false, + XMLDocument : false, XMLHttpRequest : false, XMLSerializer : false, XPathEvaluator : false, @@ -12030,346 +17436,1847 @@ exports.browser = { XPathResult : false }; -exports.devel = { - alert : false, - confirm: false, - console: false, - Debug : false, - opera : false, - prompt : false +exports.devel = { + alert : false, + confirm: false, + console: false, + Debug : false, + opera : false, + prompt : false +}; + +exports.worker = { + addEventListener : true, // EventTarget + atob : true, // WindowOrWorkerGlobalScope + btoa : true, // WindowOrWorkerGlobalScope + clearInterval : true, // WindowOrWorkerGlobalScope + clearTimeout : true, // WindowOrWorkerGlobalScope + createImageBitmap : true, // WindowOrWorkerGlobalScope + dispatchEvent : true, // EventTarget + importScripts : true, + onmessage : true, + origin : true, // WindowOrWorkerGlobalScope + postMessage : true, + queueMicrotask : true, // WindowOrWorkerGlobalScope + removeEventListener : true, // EventTarget + self : true, + setInterval : true, // WindowOrWorkerGlobalScope + setTimeout : true, // WindowOrWorkerGlobalScope + FileReaderSync : true +}; + +// Widely adopted global names that are not part of ECMAScript standard +exports.nonstandard = { + escape : false, + unescape: false +}; + +// Globals provided by popular JavaScript environments. + +exports.couch = { + "require" : false, + respond : false, + getRow : false, + emit : false, + send : false, + start : false, + sum : false, + log : false, + exports : false, + module : false, + provides : false +}; + +exports.node = { + __filename : false, + __dirname : false, + arguments : false, + GLOBAL : false, + global : false, + module : false, + require : false, + Intl : false, + + // These globals are writeable because Node allows the following + // usage pattern: var Buffer = require("buffer").Buffer; + + Buffer : true, + console : true, + exports : true, + process : true, + setTimeout : true, + clearTimeout : true, + setInterval : true, + clearInterval : true, + setImmediate : true, // v0.9.1+ + clearImmediate : true, // v0.9.1+ + URL : true, // v10.0.0+ + URLSearchParams: true // v10.0.0+ +}; + +exports.browserify = { + __filename : false, + __dirname : false, + global : false, + module : false, + require : false, + Buffer : true, + exports : true, + process : true +}; + +exports.phantom = { + phantom : true, + require : true, + WebPage : true, + console : true, // in examples, but undocumented + exports : true // v1.7+ +}; + +exports.qunit = { + asyncTest : false, + deepEqual : false, + equal : false, + expect : false, + module : false, + notDeepEqual : false, + notEqual : false, + notOk : false, + notPropEqual : false, + notStrictEqual : false, + ok : false, + propEqual : false, + QUnit : false, + raises : false, + start : false, + stop : false, + strictEqual : false, + test : false, + "throws" : false +}; + +exports.rhino = { + arguments : false, + defineClass : false, + deserialize : false, + gc : false, + help : false, + importClass : false, + importPackage: false, + "java" : false, + load : false, + loadClass : false, + Packages : false, + print : false, + quit : false, + readFile : false, + readUrl : false, + runCommand : false, + seal : false, + serialize : false, + spawn : false, + sync : false, + toint32 : false, + version : false +}; + +exports.shelljs = { + target : false, + echo : false, + exit : false, + cd : false, + pwd : false, + ls : false, + find : false, + cp : false, + rm : false, + mv : false, + mkdir : false, + test : false, + cat : false, + sed : false, + grep : false, + which : false, + dirs : false, + pushd : false, + popd : false, + env : false, + exec : false, + chmod : false, + config : false, + error : false, + tempdir : false +}; + +exports.typed = { + ArrayBuffer : false, + ArrayBufferView : false, + DataView : false, + Float32Array : false, + Float64Array : false, + Int16Array : false, + Int32Array : false, + Int8Array : false, + Uint16Array : false, + Uint32Array : false, + Uint8Array : false, + Uint8ClampedArray : false +}; + +exports.wsh = { + ActiveXObject : true, + Enumerator : true, + GetObject : true, + ScriptEngine : true, + ScriptEngineBuildVersion : true, + ScriptEngineMajorVersion : true, + ScriptEngineMinorVersion : true, + VBArray : true, + WSH : true, + WScript : true, + XDomainRequest : true +}; + +// Globals provided by popular JavaScript libraries. + +exports.dojo = { + dojo : false, + dijit : false, + dojox : false, + define : false, + "require": false +}; + +exports.jquery = { + "$" : false, + jQuery : false +}; + +exports.mootools = { + "$" : false, + "$$" : false, + Asset : false, + Browser : false, + Chain : false, + Class : false, + Color : false, + Cookie : false, + Core : false, + Document : false, + DomReady : false, + DOMEvent : false, + DOMReady : false, + Drag : false, + Element : false, + Elements : false, + Event : false, + Events : false, + Fx : false, + Group : false, + Hash : false, + HtmlTable : false, + IFrame : false, + IframeShim : false, + InputValidator: false, + instanceOf : false, + Keyboard : false, + Locale : false, + Mask : false, + MooTools : false, + Native : false, + Options : false, + OverText : false, + Request : false, + Scroller : false, + Slick : false, + Slider : false, + Sortables : false, + Spinner : false, + Swiff : false, + Tips : false, + Type : false, + typeOf : false, + URI : false, + Window : false +}; + +exports.prototypejs = { + "$" : false, + "$$" : false, + "$A" : false, + "$F" : false, + "$H" : false, + "$R" : false, + "$break" : false, + "$continue" : false, + "$w" : false, + Abstract : false, + Ajax : false, + Class : false, + Enumerable : false, + Element : false, + Event : false, + Field : false, + Form : false, + Hash : false, + Insertion : false, + ObjectRange : false, + PeriodicalExecuter: false, + Position : false, + Prototype : false, + Selector : false, + Template : false, + Toggle : false, + Try : false, + Autocompleter : false, + Builder : false, + Control : false, + Draggable : false, + Draggables : false, + Droppables : false, + Effect : false, + Sortable : false, + SortableObserver : false, + Sound : false, + Scriptaculous : false +}; + +exports.yui = { + YUI : false, + Y : false, + YUI_config: false +}; + +exports.mocha = { + // Global (for config etc.) + mocha : false, + // BDD + describe : false, + xdescribe : false, + context : false, + xcontext : false, + it : false, + xit : false, + specify : false, + xspecify : false, + before : false, + after : false, + beforeEach : false, + afterEach : false, + // TDD + suite : false, + test : false, + setup : false, + teardown : false, + suiteSetup : false, + suiteTeardown : false +}; + +exports.jasmine = { + jasmine : false, + describe : false, + xdescribe : false, + it : false, + xit : false, + beforeEach : false, + afterEach : false, + setFixtures : false, + loadFixtures: false, + spyOn : false, + expect : false, + // Jasmine 1.3 + runs : false, + waitsFor : false, + waits : false, + // Jasmine 2.1 + beforeAll : false, + afterAll : false, + fail : false, + fdescribe : false, + fit : false, + pending : false, + // Jasmine 2.6 + spyOnProperty: false +}; + +},{}],"/node_modules/assert/assert.js":[function(_dereq_,module,exports){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// 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 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. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = _dereq_('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && !isFinite(value)) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + // if one is a primitive, the other must be same + if (util.isPrimitive(a) || util.isPrimitive(b)) { + return a === b; + } + var aIsArgs = isArguments(a), + bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +},{"util/":"/node_modules/assert/node_modules/util/util.js"}],"/node_modules/assert/node_modules/inherits/inherits_browser.js":[function(_dereq_,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],"/node_modules/assert/node_modules/util/support/isBufferBrowser.js":[function(_dereq_,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],"/node_modules/assert/node_modules/util/util.js":[function(_dereq_,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// 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. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = _dereq_('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = _dereq_('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":"/node_modules/assert/node_modules/util/support/isBufferBrowser.js","_process":"/node_modules/process/browser.js","inherits":"/node_modules/assert/node_modules/inherits/inherits_browser.js"}],"/node_modules/events/events.js":[function(_dereq_,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// 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. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; }; -exports.worker = { - importScripts : true, - postMessage : true, - self : true, - FileReaderSync : true -}; +EventEmitter.prototype.addListener = function(type, listener) { + var m; -// Widely adopted global names that are not part of ECMAScript standard -exports.nonstandard = { - escape : false, - unescape: false -}; + if (!isFunction(listener)) + throw TypeError('listener must be a function'); -// Globals provided by popular JavaScript environments. + if (!this._events) + this._events = {}; -exports.couch = { - "require" : false, - respond : false, - getRow : false, - emit : false, - send : false, - start : false, - sum : false, - log : false, - exports : false, - module : false, - provides : false -}; + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); -exports.node = { - __filename : false, - __dirname : false, - GLOBAL : false, - global : false, - module : false, - require : false, + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; - // These globals are writeable because Node allows the following - // usage pattern: var Buffer = require("buffer").Buffer; + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } - Buffer : true, - console : true, - exports : true, - process : true, - setTimeout : true, - clearTimeout : true, - setInterval : true, - clearInterval : true, - setImmediate : true, // v0.9.1+ - clearImmediate: true // v0.9.1+ -}; + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } -exports.browserify = { - __filename : false, - __dirname : false, - global : false, - module : false, - require : false, - Buffer : true, - exports : true, - process : true + return this; }; -exports.phantom = { - phantom : true, - require : true, - WebPage : true, - console : true, // in examples, but undocumented - exports : true // v1.7+ -}; +EventEmitter.prototype.on = EventEmitter.prototype.addListener; -exports.qunit = { - asyncTest : false, - deepEqual : false, - equal : false, - expect : false, - module : false, - notDeepEqual : false, - notEqual : false, - notPropEqual : false, - notStrictEqual : false, - ok : false, - propEqual : false, - QUnit : false, - raises : false, - start : false, - stop : false, - strictEqual : false, - test : false, - "throws" : false +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; }; -exports.rhino = { - defineClass : false, - deserialize : false, - gc : false, - help : false, - importClass : false, - importPackage: false, - "java" : false, - load : false, - loadClass : false, - Packages : false, - print : false, - quit : false, - readFile : false, - readUrl : false, - runCommand : false, - seal : false, - serialize : false, - spawn : false, - sync : false, - toint32 : false, - version : false +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; }; -exports.shelljs = { - target : false, - echo : false, - exit : false, - cd : false, - pwd : false, - ls : false, - find : false, - cp : false, - rm : false, - mv : false, - mkdir : false, - test : false, - cat : false, - sed : false, - grep : false, - which : false, - dirs : false, - pushd : false, - popd : false, - env : false, - exec : false, - chmod : false, - config : false, - error : false, - tempdir : false +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; }; -exports.typed = { - ArrayBuffer : false, - ArrayBufferView : false, - DataView : false, - Float32Array : false, - Float64Array : false, - Int16Array : false, - Int32Array : false, - Int8Array : false, - Uint16Array : false, - Uint32Array : false, - Uint8Array : false, - Uint8ClampedArray : false +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; }; -exports.wsh = { - ActiveXObject : true, - Enumerator : true, - GetObject : true, - ScriptEngine : true, - ScriptEngineBuildVersion : true, - ScriptEngineMajorVersion : true, - ScriptEngineMinorVersion : true, - VBArray : true, - WSH : true, - WScript : true, - XDomainRequest : true +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; }; -// Globals provided by popular JavaScript libraries. +function isFunction(arg) { + return typeof arg === 'function'; +} -exports.dojo = { - dojo : false, - dijit : false, - dojox : false, - define : false, - "require": false -}; +function isNumber(arg) { + return typeof arg === 'number'; +} -exports.jquery = { - "$" : false, - jQuery : false -}; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} -exports.mootools = { - "$" : false, - "$$" : false, - Asset : false, - Browser : false, - Chain : false, - Class : false, - Color : false, - Cookie : false, - Core : false, - Document : false, - DomReady : false, - DOMEvent : false, - DOMReady : false, - Drag : false, - Element : false, - Elements : false, - Event : false, - Events : false, - Fx : false, - Group : false, - Hash : false, - HtmlTable : false, - IFrame : false, - IframeShim : false, - InputValidator: false, - instanceOf : false, - Keyboard : false, - Locale : false, - Mask : false, - MooTools : false, - Native : false, - Options : false, - OverText : false, - Request : false, - Scroller : false, - Slick : false, - Slider : false, - Sortables : false, - Spinner : false, - Swiff : false, - Tips : false, - Type : false, - typeOf : false, - URI : false, - Window : false -}; +function isUndefined(arg) { + return arg === void 0; +} -exports.prototypejs = { - "$" : false, - "$$" : false, - "$A" : false, - "$F" : false, - "$H" : false, - "$R" : false, - "$break" : false, - "$continue" : false, - "$w" : false, - Abstract : false, - Ajax : false, - Class : false, - Enumerable : false, - Element : false, - Event : false, - Field : false, - Form : false, - Hash : false, - Insertion : false, - ObjectRange : false, - PeriodicalExecuter: false, - Position : false, - Prototype : false, - Selector : false, - Template : false, - Toggle : false, - Try : false, - Autocompleter : false, - Builder : false, - Control : false, - Draggable : false, - Draggables : false, - Droppables : false, - Effect : false, - Sortable : false, - SortableObserver : false, - Sound : false, - Scriptaculous : false -}; +},{}],"/node_modules/process/browser.js":[function(_dereq_,module,exports){ +// shim for using process in browser +var process = module.exports = {}; -exports.yui = { - YUI : false, - Y : false, - YUI_config: false -}; +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. -exports.mocha = { - // Global (for config etc.) - mocha : false, - // BDD - describe : false, - xdescribe : false, - it : false, - xit : false, - context : false, - xcontext : false, - before : false, - after : false, - beforeEach : false, - afterEach : false, - // TDD - suite : false, - test : false, - setup : false, - teardown : false, - suiteSetup : false, - suiteTeardown : false +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } }; -exports.jasmine = { - jasmine : false, - describe : false, - xdescribe : false, - it : false, - xit : false, - beforeEach : false, - afterEach : false, - setFixtures : false, - loadFixtures: false, - spyOn : false, - expect : false, - // Jasmine 1.3 - runs : false, - waitsFor : false, - waits : false, - // Jasmine 2.1 - beforeAll : false, - afterAll : false, - fail : false, - fdescribe : false, - fit : false, - pending : false +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); }; -},{}]},{},["/node_modules/jshint/src/jshint.js"]); +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],"/node_modules/util/node_modules/inherits/inherits_browser.js":[function(_dereq_,module,exports){ +arguments[4]["/node_modules/assert/node_modules/inherits/inherits_browser.js"][0].apply(exports,arguments) +},{}],"/node_modules/util/support/isBufferBrowser.js":[function(_dereq_,module,exports){ +arguments[4]["/node_modules/assert/node_modules/util/support/isBufferBrowser.js"][0].apply(exports,arguments) +},{}],"/node_modules/util/util.js":[function(_dereq_,module,exports){ +arguments[4]["/node_modules/assert/node_modules/util/util.js"][0].apply(exports,arguments) +},{"./support/isBuffer":"/node_modules/util/support/isBufferBrowser.js","_process":"/node_modules/process/browser.js","inherits":"/node_modules/util/node_modules/inherits/inherits_browser.js"}]},{},["/../../../jshint/src/jshint.js"]); }); \ No newline at end of file diff --git a/lib/ace/mode/javascript_test.js b/lib/ace/mode/javascript_test.js deleted file mode 100644 index fbe79ffbf5e..00000000000 --- a/lib/ace/mode/javascript_test.js +++ /dev/null @@ -1,213 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") { - require("amd-loader"); -} - -define(function(require, exports, module) { -"use strict"; - -var EditSession = require("../edit_session").EditSession; -var Tokenizer = require("../tokenizer").Tokenizer; -var JavaScriptMode = require("./javascript").Mode; -var assert = require("../test/assertions"); - -module.exports = { - setUp : function() { - this.mode = new JavaScriptMode(); - }, - - "test: getTokenizer() (smoke test)" : function() { - var tokenizer = this.mode.getTokenizer(); - - assert.ok(tokenizer instanceof Tokenizer); - - var tokens = tokenizer.getLineTokens("'juhu'", "start").tokens; - assert.equal("string", tokens[0].type); - }, - - "test: toggle comment lines should prepend '//' to each line" : function() { - var session = new EditSession([" abc", "cde", "fg"]); - session.setTabSize(1); - - this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal(["// abc", "// cde", "fg"].join("\n"), session.toString()); - }, - - "test: toggle comment on commented lines should remove leading '//' chars" : function() { - var session = new EditSession(["// abc", "//cde", "fg"]); - session.setTabSize(1); - - this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); - }, - - "test: toggle comment on all empty lines" : function() { - var session = new EditSession([" ", " ", " "]); - session.setTabSize(1); - - this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal([" // ", " // ", " "].join("\n"), session.toString()); - }, - - "test: toggle comment with empty lines" : function() { - var session = new EditSession([ - " abc", - "", - " cde", - " fg"]); - - var initial = session.toString(); - this.mode.toggleCommentLines("start", session, 0, 3); - assert.equal([ - " // abc", - "", - " // cde", - " // fg"].join("\n"), - session.toString() - ); - this.mode.toggleCommentLines("start", session, 0, 3); - assert.equal(initial, session.toString()); - }, - - "test: toggle comment lines twice should return the original text" : function() { - var session = new EditSession([" abc", "cde", "fg"]); - - this.mode.toggleCommentLines("start", session, 0, 2); - this.mode.toggleCommentLines("start", session, 0, 2); - assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); - }, - - "test: toggle comment on multiple lines with one commented line prepend '//' to each line" : function() { - var session = new EditSession([" // abc", " //cde", " fg"]); - session.setTabSize(1); - this.mode.toggleCommentLines("start", session, 0, 2); - assert.equal([" // // abc", " // //cde", " // fg"].join("\n"), session.toString()); - }, - - "test: toggle comment on a comment line with leading white space": function() { - var session = new EditSession(["//cde", " //fg"]); - - this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal(["cde", " fg"].join("\n"), session.toString()); - }, - - "test: toggle comment lines should take tabsize into account" : function() { - var session = new EditSession([" // abc", " // cde", "// fg"]); - session.setTabSize(2); - this.mode.toggleCommentLines("start", session, 0, 2); - assert.equal([" abc", " cde", " fg"].join("\n"), session.toString()); - session.setTabSize(4); - this.mode.toggleCommentLines("start", session, 0, 2); - assert.equal(["// abc", "// cde", "// fg"].join("\n"), session.toString()); - this.mode.toggleCommentLines("start", session, 0, 2); - assert.equal([" abc", " cde", " fg"].join("\n"), session.toString()); - - session.insert({row: 0, column: 0}, " "); - this.mode.toggleCommentLines("start", session, 0, 2); - assert.equal(["// abc", "// cde", "// fg"].join("\n"), session.toString()); - }, - //there doesn't seem to be any way to make this work - "!test: togglecomment on line with one space" : function() { - var session = new EditSession([" abc", " // cde", "// fg"]); - var initialValue = session + ""; - session.setTabSize(4); - this.mode.toggleCommentLines("start", session, 0, 0); - this.mode.toggleCommentLines("start", session, 0, 0); - assert.equal(initialValue, session.toString()); - }, - - "test: auto indent after opening brace" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", "if () {", " ")); - }, - - "test: auto indent after case" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", "case 'juhu':", " ")); - }, - - "test: no auto indent in object literal" : function() { - assert.equal("", this.mode.getNextLineIndent("start", "{ 'juhu':", " ")); - }, - - "test: no auto indent after opening brace in multi line comment" : function() { - assert.equal("", this.mode.getNextLineIndent("start", "/*if () {", " ")); - assert.equal(" ", this.mode.getNextLineIndent("comment", " abcd", " ")); - }, - - "test: no auto indent after opening brace in single line comment" : function() { - assert.equal("", this.mode.getNextLineIndent("start", "//if () {", " ")); - assert.equal(" ", this.mode.getNextLineIndent("start", " //if () {", " ")); - }, - - "test: no auto indent should add to existing indent" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " if () {", " ")); - assert.equal(" ", this.mode.getNextLineIndent("start", " cde", " ")); - assert.equal(" ", this.mode.getNextLineIndent("start", "function foo(items) {", " ")); - }, - - "test: special indent in doc comments" : function() { - assert.equal(" * ", this.mode.getNextLineIndent("doc-start", "/**", " ")); - assert.equal(" * ", this.mode.getNextLineIndent("doc-start", " /**", " ")); - assert.equal(" * ", this.mode.getNextLineIndent("doc-start", " *", " ")); - assert.equal(" * ", this.mode.getNextLineIndent("doc-start", " *", " ")); - assert.equal(" ", this.mode.getNextLineIndent("doc-start", " abc", " ")); - }, - - "test: no indent after doc comments" : function() { - assert.equal("", this.mode.getNextLineIndent("doc-start", " */", " ")); - }, - - "test: trigger outdent if line is space and new text starts with closing brace" : function() { - assert.ok(this.mode.checkOutdent("start", " ", " }")); - assert.ok(!this.mode.checkOutdent("start", " a ", " }")); - assert.ok(!this.mode.checkOutdent("start", "", "}")); - assert.ok(!this.mode.checkOutdent("start", " ", "a }")); - assert.ok(!this.mode.checkOutdent("start", " }", "}")); - }, - - "test: auto outdent should indent the line with the same indent as the line with the matching opening brace" : function() { - var session = new EditSession([" function foo() {", " bla", " }"], new JavaScriptMode()); - this.mode.autoOutdent("start", session, 2); - assert.equal(" }", session.getLine(2)); - }, - - "test: no auto outdent if no matching brace is found" : function() { - var session = new EditSession([" function foo()", " bla", " }"]); - this.mode.autoOutdent("start", session, 2); - assert.equal(" }", session.getLine(2)); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/mode/javascript_worker.js b/lib/ace/mode/javascript_worker.js index b97437350ac..3bf6ceb6f38 100644 --- a/lib/ace/mode/javascript_worker.js +++ b/lib/ace/mode/javascript_worker.js @@ -79,7 +79,7 @@ oop.inherits(JavaScriptWorker, Mirror); this.options = options || { // undef: true, // unused: true, - esnext: true, + esversion: 11, moz: true, devel: true, browser: true, @@ -102,17 +102,6 @@ oop.inherits(JavaScriptWorker, Mirror); this.doc.getValue() && this.deferredUpdate.schedule(100); }; - this.isValidJS = function(str) { - try { - // evaluated code can only create variables in this function - eval("throw 0;" + str); - } catch(e) { - if (e === 0) - return true; - } - return false; - }; - this.onUpdate = function() { var value = this.doc.getValue(); value = value.replace(/^#!.*\n/, "\n"); @@ -120,9 +109,6 @@ oop.inherits(JavaScriptWorker, Mirror); return this.sender.emit("annotate", []); var errors = []; - // jshint reports many false errors - // report them as error only if code is actually invalid - var maxErrorLevel = this.isValidJS(value) ? "warning" : "error"; // var start = new Date(); lint(value, this.options, this.options.globals); @@ -139,7 +125,7 @@ oop.inherits(JavaScriptWorker, Mirror); if (raw == "Missing semicolon.") { var str = error.evidence.substr(error.character); str = str.charAt(str.search(/\S/)); - if (maxErrorLevel == "error" && str && /[\w\d{(['"]/.test(str)) { + if (str && /[\w\d{(['"]/.test(str)) { error.reason = 'Missing ";" before statement'; type = "error"; } else { @@ -154,7 +140,7 @@ oop.inherits(JavaScriptWorker, Mirror); } else if (errorsRe.test(raw)) { errorAdded = true; - type = maxErrorLevel; + type = "error"; } else if (raw == "'{a}' is not defined.") { type = "warning"; diff --git a/lib/ace/mode/json.js b/lib/ace/mode/json.js deleted file mode 100644 index cfb00daba7d..00000000000 --- a/lib/ace/mode/json.js +++ /dev/null @@ -1,93 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var HighlightRules = require("./json_highlight_rules").JsonHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; -var WorkerClient = require("../worker/worker_client").WorkerClient; - -var Mode = function() { - this.HighlightRules = HighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.createWorker = function(session) { - var worker = new WorkerClient(["ace"], "ace/mode/json_worker", "JsonWorker"); - worker.attachToDocument(session.getDocument()); - - worker.on("annotate", function(e) { - session.setAnnotations(e.data); - }); - - worker.on("terminate", function() { - session.clearAnnotations(); - }); - - return worker; - }; - - - this.$id = "ace/mode/json"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/json_highlight_rules.js b/lib/ace/mode/json_highlight_rules.js deleted file mode 100644 index 072a1020380..00000000000 --- a/lib/ace/mode/json_highlight_rules.js +++ /dev/null @@ -1,108 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var JsonHighlightRules = function() { - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - this.$rules = { - "start" : [ - { - token : "variable", // single line - regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)' - }, { - token : "string", // single line - regex : '"', - next : "string" - }, { - token : "constant.numeric", // hex - regex : "0[xX][0-9a-fA-F]+\\b" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" - }, { - token : "text", // single quoted strings are not allowed - regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, { - token : "comment", // comments are not allowed, but who cares? - regex : "\\/\\/.*$" - }, { - token : "comment.start", // comments are not allowed, but who cares? - regex : "\\/\\*", - next : "comment" - }, { - token : "paren.lparen", - regex : "[[({]" - }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" - } - ], - "string" : [ - { - token : "constant.language.escape", - regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/ - }, { - token : "string", - regex : '"|$', - next : "start" - }, { - defaultToken : "string" - } - ], - "comment" : [ - { - token : "comment.end", // comments are not allowed, but who cares? - regex : "\\*\\/", - next : "start" - }, { - defaultToken: "comment" - } - ] - }; - -}; - -oop.inherits(JsonHighlightRules, TextHighlightRules); - -exports.JsonHighlightRules = JsonHighlightRules; -}); diff --git a/lib/ace/mode/jsoniq.js b/lib/ace/mode/jsoniq.js index 64dc9541f62..a02ee1608c3 100644 --- a/lib/ace/mode/jsoniq.js +++ b/lib/ace/mode/jsoniq.js @@ -1,32 +1,3 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { "use strict"; @@ -197,6 +168,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/jsoniq"; + this.snippetFileId = "ace/snippets/jsoniq"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/lib/ace/mode/jsp.js b/lib/ace/mode/jsp.js deleted file mode 100644 index c1cb02548c8..00000000000 --- a/lib/ace/mode/jsp.js +++ /dev/null @@ -1,55 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var JspHighlightRules = require("./jsp_highlight_rules").JspHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = JspHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.$id = "ace/mode/jsp"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/jsp_highlight_rules.js b/lib/ace/mode/jsp_highlight_rules.js deleted file mode 100644 index 6af5563a2e0..00000000000 --- a/lib/ace/mode/jsp_highlight_rules.js +++ /dev/null @@ -1,91 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; -var JavaHighlightRules = require("./java_highlight_rules").JavaHighlightRules; - -var JspHighlightRules = function() { - HtmlHighlightRules.call(this); - - var builtinVariables = 'request|response|out|session|' + - 'application|config|pageContext|page|Exception'; - - var keywords = 'page|include|taglib'; - - var startRules = [ - { - token : "comment", - regex : "<%--", - push : "jsp-dcomment" - }, { - token : "meta.tag", // jsp open tag - regex : "<%@?|<%=?|<%!?|]+>", - push : "jsp-start" - } - ]; - - var endRules = [ - { - token : "meta.tag", // jsp close tag - regex : "%>|<\\/jsp:[^>]+>", - next : "pop" - }, { - token: "variable.language", - regex : builtinVariables - }, { - token: "keyword", - regex : keywords - } - ]; - - for (var key in this.$rules) - this.$rules[key].unshift.apply(this.$rules[key], startRules); - - this.embedRules(JavaHighlightRules, "jsp-", endRules, ["start"]); - - this.addRules({ - "jsp-dcomment" : [{ - token : "comment", - regex : ".*?--%>", - next : "pop" - }] - }); - - this.normalizeRules(); -}; - -oop.inherits(JspHighlightRules, HtmlHighlightRules); - -exports.JspHighlightRules = JspHighlightRules; -}); diff --git a/lib/ace/mode/jssm.js b/lib/ace/mode/jssm.js deleted file mode 100644 index b48b8962ee7..00000000000 --- a/lib/ace/mode/jssm.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var JSSMHighlightRules = require("./jssm_highlight_rules").JSSMHighlightRules; -// TODO: pick appropriate fold mode -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = JSSMHighlightRules; - this.foldingRules = new FoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - // Extra logic goes here. - this.$id = "ace/mode/jssm"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/jsx.js b/lib/ace/mode/jsx.js deleted file mode 100644 index 2406a232287..00000000000 --- a/lib/ace/mode/jsx.js +++ /dev/null @@ -1,56 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var JsxHighlightRules = require("./jsx_highlight_rules").JsxHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -function Mode() { - this.HighlightRules = JsxHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -} -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/jsx"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/jsx_highlight_rules.js b/lib/ace/mode/jsx_highlight_rules.js deleted file mode 100644 index 394aed5c446..00000000000 --- a/lib/ace/mode/jsx_highlight_rules.js +++ /dev/null @@ -1,119 +0,0 @@ -define(function(require, exports, module) { -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var JsxHighlightRules = function() { - var keywords = lang.arrayToMap( - ("break|do|instanceof|typeof|case|else|new|var|catch|finally|return|void|continue|for|switch|default|while|function|this|" + - "if|throw|" + - "delete|in|try|" + - "class|extends|super|import|from|into|implements|interface|static|mixin|override|abstract|final|" + - "number|int|string|boolean|variant|" + - "log|assert").split("|") - ); - - var buildinConstants = lang.arrayToMap( - ("null|true|false|NaN|Infinity|__FILE__|__LINE__|undefined").split("|") - ); - - var reserved = lang.arrayToMap( - ("debugger|with|" + - "const|export|" + - "let|private|public|yield|protected|" + - "extern|native|as|operator|__fake__|__readonly__").split("|") - ); - - var identifierRe = "[a-zA-Z_][a-zA-Z0-9_]*\\b"; - - this.$rules = { - "start" : [ - { - token : "comment", - regex : "\\/\\/.*$" - }, - DocCommentHighlightRules.getStartRule("doc-start"), - { - token : "comment", // multi line comment - regex : "\\/\\*", - next : "comment" - }, { - token : "string.regexp", - regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" - }, { - token : "string", // single line - regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - }, { - token : "string", // single line - regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, { - token : "constant.numeric", // hex - regex : "0[xX][0-9a-fA-F]+\\b" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" - }, { - token : [ - "storage.type", - "text", - "entity.name.function" - ], - regex : "(function)(\\s+)(" + identifierRe + ")" - }, { - token : function(value) { - if (value == "this") - return "variable.language"; - else if (value == "function") - return "storage.type"; - else if (keywords.hasOwnProperty(value) || reserved.hasOwnProperty(value)) - return "keyword"; - else if (buildinConstants.hasOwnProperty(value)) - return "constant.language"; - else if (/^_?[A-Z][a-zA-Z0-9_]*$/.test(value)) - return "language.support.class"; - else - return "identifier"; - }, - // TODO: Unicode escape sequences - // TODO: Unicode identifiers - regex : identifierRe - }, { - token : "keyword.operator", - regex : "!|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" - }, { - token : "punctuation.operator", - regex : "\\?|\\:|\\,|\\;|\\." - }, { - token : "paren.lparen", - regex : "[[({<]" - }, { - token : "paren.rparen", - regex : "[\\])}>]" - }, { - token : "text", - regex : "\\s+" - } - ], - "comment" : [ - { - token : "comment", // closing comment - regex : "\\*\\/", - next : "start" - }, { - defaultToken : "comment" - } - ] - }; - - this.embedRules(DocCommentHighlightRules, "doc-", - [ DocCommentHighlightRules.getEndRule("start") ]); -}; - -oop.inherits(JsxHighlightRules, TextHighlightRules); - -exports.JsxHighlightRules = JsxHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/julia.js b/lib/ace/mode/julia.js deleted file mode 100644 index 62f08c4fb7e..00000000000 --- a/lib/ace/mode/julia.js +++ /dev/null @@ -1,63 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var JuliaHighlightRules = require("./julia_highlight_rules").JuliaHighlightRules; -// TODO: pick appropriate fold mode -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = JuliaHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "#"; - this.blockComment = ""; - this.$id = "ace/mode/julia"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/kotlin.js b/lib/ace/mode/kotlin.js deleted file mode 100644 index 3f9b0f63cf8..00000000000 --- a/lib/ace/mode/kotlin.js +++ /dev/null @@ -1,59 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var KotlinHighlightRules = require("./kotlin_highlight_rules").KotlinHighlightRules; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = KotlinHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = new CstyleBehaviour(); -}; -oop.inherits(Mode, TextMode); - -(function() { - // this.lineCommentStart = ""/\\*""; - // this.blockComment = {start: ""/*"", end: ""*/""}; - // Extra logic goes here. - this.$id = "ace/mode/kotlin"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/kotlin_highlight_rules.js b/lib/ace/mode/kotlin_highlight_rules.js deleted file mode 100644 index 97bda177374..00000000000 --- a/lib/ace/mode/kotlin_highlight_rules.js +++ /dev/null @@ -1,663 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* This file was autogenerated from Kotlin.tmLanguage (uuid: ) */ -/**************************************************************************************** - * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * - * fileTypes * - ****************************************************************************************/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var KotlinHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { - start: [{ - include: "#comments" - }, { - token: [ - "text", - "keyword.other.kotlin", - "text", - "entity.name.package.kotlin", - "text" - ], - regex: /^(\s*)(package)\b(?:(\s*)([^ ;$]+)(\s*))?/ - }, { - include: "#imports" - }, { - include: "#statements" - }], - "#classes": [{ - token: "text", - regex: /(?=\s*(?:companion|class|object|interface))/, - push: [{ - token: "text", - regex: /}|(?=$)/, - next: "pop" - }, { - token: ["keyword.other.kotlin", "text"], - regex: /\b((?:companion\s*)?)(class|object|interface)\b/, - push: [{ - token: "text", - regex: /(?=<|{|\(|:)/, - next: "pop" - }, { - token: "keyword.other.kotlin", - regex: /\bobject\b/ - }, { - token: "entity.name.type.class.kotlin", - regex: /\w+/ - }] - }, { - token: "text", - regex: //, - next: "pop" - }, { - include: "#generics" - }] - }, { - token: "text", - regex: /\(/, - push: [{ - token: "text", - regex: /\)/, - next: "pop" - }, { - include: "#parameters" - }] - }, { - token: "keyword.operator.declaration.kotlin", - regex: /:/, - push: [{ - token: "text", - regex: /(?={|$)/, - next: "pop" - }, { - token: "entity.other.inherited-class.kotlin", - regex: /\w+/ - }, { - token: "text", - regex: /\(/, - push: [{ - token: "text", - regex: /\)/, - next: "pop" - }, { - include: "#expressions" - }] - }] - }, { - token: "text", - regex: /\{/, - push: [{ - token: "text", - regex: /\}/, - next: "pop" - }, { - include: "#statements" - }] - }] - }], - "#comments": [{ - token: "punctuation.definition.comment.kotlin", - regex: /\/\*/, - push: [{ - token: "punctuation.definition.comment.kotlin", - regex: /\*\//, - next: "pop" - }, { - defaultToken: "comment.block.kotlin" - }] - }, { - token: [ - "text", - "punctuation.definition.comment.kotlin", - "comment.line.double-slash.kotlin" - ], - regex: /(\s*)(\/\/)(.*$)/ - }], - "#constants": [{ - token: "constant.language.kotlin", - regex: /\b(?:true|false|null|this|super)\b/ - }, { - token: "constant.numeric.kotlin", - regex: /\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:(?:e|E)(?:\+|-)?[0-9]+)?)(?:[LlFfUuDd]|UL|ul)?\b/ - }, { - token: "constant.other.kotlin", - regex: /\b[A-Z][A-Z0-9_]+\b/ - }], - "#expressions": [{ - token: "text", - regex: /\(/, - push: [{ - token: "text", - regex: /\)/, - next: "pop" - }, { - include: "#expressions" - }] - }, { - include: "#types" - }, { - include: "#strings" - }, { - include: "#constants" - }, { - include: "#comments" - }, { - include: "#keywords" - }], - "#functions": [{ - token: "text", - regex: /(?=\s*fun)/, - push: [{ - token: "text", - regex: /}|(?=$)/, - next: "pop" - }, { - token: "keyword.other.kotlin", - regex: /\bfun\b/, - push: [{ - token: "text", - regex: /(?=\()/, - next: "pop" - }, { - token: "text", - regex: //, - next: "pop" - }, { - include: "#generics" - }] - }, { - token: ["text", "entity.name.function.kotlin"], - regex: /((?:[\.<\?>\w]+\.)?)(\w+)/ - }] - }, { - token: "text", - regex: /\(/, - push: [{ - token: "text", - regex: /\)/, - next: "pop" - }, { - include: "#parameters" - }] - }, { - token: "keyword.operator.declaration.kotlin", - regex: /:/, - push: [{ - token: "text", - regex: /(?={|=|$)/, - next: "pop" - }, { - include: "#types" - }] - }, { - token: "text", - regex: /\{/, - push: [{ - token: "text", - regex: /(?=\})/, - next: "pop" - }, { - include: "#statements" - }] - }, { - token: "keyword.operator.assignment.kotlin", - regex: /=/, - push: [{ - token: "text", - regex: /(?=$)/, - next: "pop" - }, { - include: "#expressions" - }] - }] - }], - "#generics": [{ - token: "keyword.operator.declaration.kotlin", - regex: /:/, - push: [{ - token: "text", - regex: /(?=,|>)/, - next: "pop" - }, { - include: "#types" - }] - }, { - include: "#keywords" - }, { - token: "storage.type.generic.kotlin", - regex: /\w+/ - }], - "#getters-and-setters": [{ - token: ["entity.name.function.kotlin", "text"], - regex: /\b(get)\b(\s*\(\s*\))/, - push: [{ - token: "text", - regex: /\}|(?=\bset\b)|$/, - next: "pop" - }, { - token: "keyword.operator.assignment.kotlin", - regex: /=/, - push: [{ - token: "text", - regex: /(?=$|\bset\b)/, - next: "pop" - }, { - include: "#expressions" - }] - }, { - token: "text", - regex: /\{/, - push: [{ - token: "text", - regex: /\}/, - next: "pop" - }, { - include: "#expressions" - }] - }] - }, { - token: ["entity.name.function.kotlin", "text"], - regex: /\b(set)\b(\s*)(?=\()/, - push: [{ - token: "text", - regex: /\}|(?=\bget\b)|$/, - next: "pop" - }, { - token: "text", - regex: /\(/, - push: [{ - token: "text", - regex: /\)/, - next: "pop" - }, { - include: "#parameters" - }] - }, { - token: "keyword.operator.assignment.kotlin", - regex: /=/, - push: [{ - token: "text", - regex: /(?=$|\bset\b)/, - next: "pop" - }, { - include: "#expressions" - }] - }, { - token: "text", - regex: /\{/, - push: [{ - token: "text", - regex: /\}/, - next: "pop" - }, { - include: "#expressions" - }] - }] - }], - "#imports": [{ - token: [ - "text", - "keyword.other.kotlin", - "text", - "keyword.other.kotlin" - ], - regex: /^(\s*)(import)(\s+[^ $]+\s+)((?:as)?)/ - }], - "#keywords": [{ - token: "storage.modifier.kotlin", - regex: /\b(?:var|val|public|private|protected|abstract|final|enum|open|attribute|annotation|override|inline|var|val|vararg|lazy|in|out|internal|data|tailrec|operator|infix|const|yield|typealias|typeof)\b/ - }, { - token: "keyword.control.catch-exception.kotlin", - regex: /\b(?:try|catch|finally|throw)\b/ - }, { - token: "keyword.control.kotlin", - regex: /\b(?:if|else|while|for|do|return|when|where|break|continue)\b/ - }, { - token: "keyword.operator.kotlin", - regex: /\b(?:in|is|as|assert)\b/ - }, { - token: "keyword.operator.comparison.kotlin", - regex: /==|!=|===|!==|<=|>=|<|>/ - }, { - token: "keyword.operator.assignment.kotlin", - regex: /=/ - }, { - token: "keyword.operator.declaration.kotlin", - regex: /:/ - }, { - token: "keyword.operator.dot.kotlin", - regex: /\./ - }, { - token: "keyword.operator.increment-decrement.kotlin", - regex: /\-\-|\+\+/ - }, { - token: "keyword.operator.arithmetic.kotlin", - regex: /\-|\+|\*|\/|%/ - }, { - token: "keyword.operator.arithmetic.assign.kotlin", - regex: /\+=|\-=|\*=|\/=/ - }, { - token: "keyword.operator.logical.kotlin", - regex: /!|&&|\|\|/ - }, { - token: "keyword.operator.range.kotlin", - regex: /\.\./ - }, { - token: "punctuation.terminator.kotlin", - regex: /;/ - }], - "#namespaces": [{ - token: "keyword.other.kotlin", - regex: /\bnamespace\b/ - }, { - token: "text", - regex: /\{/, - push: [{ - token: "text", - regex: /\}/, - next: "pop" - }, { - include: "#statements" - }] - }], - "#parameters": [{ - token: "keyword.operator.declaration.kotlin", - regex: /:/, - push: [{ - token: "text", - regex: /(?=,|\)|=)/, - next: "pop" - }, { - include: "#types" - }] - }, { - token: "keyword.operator.declaration.kotlin", - regex: /=/, - push: [{ - token: "text", - regex: /(?=,|\))/, - next: "pop" - }, { - include: "#expressions" - }] - }, { - include: "#keywords" - }, { - token: "variable.parameter.function.kotlin", - regex: /\w+/ - }], - "#statements": [{ - include: "#namespaces" - }, { - include: "#typedefs" - }, { - include: "#classes" - }, { - include: "#functions" - }, { - include: "#variables" - }, { - include: "#getters-and-setters" - }, { - include: "#expressions" - }], - "#strings": [{ - token: "punctuation.definition.string.begin.kotlin", - regex: /"""/, - push: [{ - token: "punctuation.definition.string.end.kotlin", - regex: /"""/, - next: "pop" - }, { - token: "variable.parameter.template.kotlin", - regex: /\$\w+|\$\{[^\}]+\}/ - }, { - token: "constant.character.escape.kotlin", - regex: /\\./ - }, { - defaultToken: "string.quoted.third.kotlin" - }] - }, { - token: "punctuation.definition.string.begin.kotlin", - regex: /"/, - push: [{ - token: "punctuation.definition.string.end.kotlin", - regex: /"/, - next: "pop" - }, { - token: "variable.parameter.template.kotlin", - regex: /\$\w+|\$\{[^\}]+\}/ - }, { - token: "constant.character.escape.kotlin", - regex: /\\./ - }, { - defaultToken: "string.quoted.double.kotlin" - }] - }, { - token: "punctuation.definition.string.begin.kotlin", - regex: /'/, - push: [{ - token: "punctuation.definition.string.end.kotlin", - regex: /'/, - next: "pop" - }, { - token: "constant.character.escape.kotlin", - regex: /\\./ - }, { - defaultToken: "string.quoted.single.kotlin" - }] - }, { - token: "punctuation.definition.string.begin.kotlin", - regex: /`/, - push: [{ - token: "punctuation.definition.string.end.kotlin", - regex: /`/, - next: "pop" - }, { - defaultToken: "string.quoted.single.kotlin" - }] - }], - "#typedefs": [{ - token: "text", - regex: /(?=\s*type)/, - push: [{ - token: "text", - regex: /(?=$)/, - next: "pop" - }, { - token: "keyword.other.kotlin", - regex: /\btype\b/ - }, { - token: "text", - regex: //, - next: "pop" - }, { - include: "#generics" - }] - }, { - include: "#expressions" - }] - }], - "#types": [{ - token: "storage.type.buildin.kotlin", - regex: /\b(?:Any|Unit|String|Int|Boolean|Char|Long|Double|Float|Short|Byte|dynamic)\b/ - }, { - token: "storage.type.buildin.array.kotlin", - regex: /\b(?:IntArray|BooleanArray|CharArray|LongArray|DoubleArray|FloatArray|ShortArray|ByteArray)\b/ - }, { - token: [ - "storage.type.buildin.collection.kotlin", - "text" - ], - regex: /\b(Array|List|Map)(<\b)/, - push: [{ - token: "text", - regex: />/, - next: "pop" - }, { - include: "#types" - }, { - include: "#keywords" - }] - }, { - token: "text", - regex: /\w+/, - next: "pop" - }, { - include: "#types" - }, { - include: "#keywords" - }] - }, { - token: ["keyword.operator.tuple.kotlin", "text"], - regex: /(#)(\()/, - push: [{ - token: "text", - regex: /\)/, - next: "pop" - }, { - include: "#expressions" - }] - }, { - token: "text", - regex: /\{/, - push: [{ - token: "text", - regex: /\}/, - next: "pop" - }, { - include: "#statements" - }] - }, { - token: "text", - regex: /\(/, - push: [{ - token: "text", - regex: /\)/, - next: "pop" - }, { - include: "#types" - }] - }, { - token: "keyword.operator.declaration.kotlin", - regex: /->/ - }], - "#variables": [{ - token: "text", - regex: /(?=\s*(?:var|val))/, - push: [{ - token: "text", - regex: /(?=:|=|$)/, - next: "pop" - }, { - token: "keyword.other.kotlin", - regex: /\b(?:var|val)\b/, - push: [{ - token: "text", - regex: /(?=:|=|$)/, - next: "pop" - }, { - token: "text", - regex: //, - next: "pop" - }, { - include: "#generics" - }] - }, { - token: ["text", "entity.name.variable.kotlin"], - regex: /((?:[\.<\?>\w]+\.)?)(\w+)/ - }] - }, { - token: "keyword.operator.declaration.kotlin", - regex: /:/, - push: [{ - token: "text", - regex: /(?==|$)/, - next: "pop" - }, { - include: "#types" - }, { - include: "#getters-and-setters" - }] - }, { - token: "keyword.operator.assignment.kotlin", - regex: /=/, - push: [{ - token: "text", - regex: /(?=$)/, - next: "pop" - }, { - include: "#expressions" - }, { - include: "#getters-and-setters" - }] - }] - }] - }; - - this.normalizeRules(); -}; - -KotlinHighlightRules.metaData = { - fileTypes: ["kt", "kts"], - name: "Kotlin", - scopeName: "source.Kotlin" -}; - - -oop.inherits(KotlinHighlightRules, TextHighlightRules); - -exports.KotlinHighlightRules = KotlinHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/latex.js b/lib/ace/mode/latex.js deleted file mode 100644 index 69256eae57c..00000000000 --- a/lib/ace/mode/latex.js +++ /dev/null @@ -1,43 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var LatexHighlightRules = require("./latex_highlight_rules").LatexHighlightRules; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var LatexFoldMode = require("./folding/latex").FoldMode; - -var Mode = function() { - this.HighlightRules = LatexHighlightRules; - this.foldingRules = new LatexFoldMode(); - this.$behaviour = new CstyleBehaviour({ braces: true }); -}; -oop.inherits(Mode, TextMode); - -(function() { - this.type = "text"; - - this.lineCommentStart = "%"; - - this.$id = "ace/mode/latex"; - - this.getMatching = function(session, row, column) { - if (row == undefined) - row = session.selection.lead; - if (typeof row == "object") { - column = row.column; - row = row.row; - } - - var startToken = session.getTokenAt(row, column); - if (!startToken) - return; - if (startToken.value == "\\begin" || startToken.value == "\\end") { - return this.foldingRules.latexBlock(session, row, column, true); - } - }; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); diff --git a/lib/ace/mode/less.js b/lib/ace/mode/less.js deleted file mode 100644 index 752558bd612..00000000000 --- a/lib/ace/mode/less.js +++ /dev/null @@ -1,92 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var LessHighlightRules = require("./less_highlight_rules").LessHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CssBehaviour = require("./behaviour/css").CssBehaviour; -var CssCompletions = require("./css_completions").CssCompletions; - -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = LessHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CssBehaviour(); - this.$completer = new CssCompletions(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - // ignore braces in comments - var tokens = this.getTokenizer().getLineTokens(line, state).tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - var match = line.match(/^.*\{\s*$/); - if (match) { - indent += tab; - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.getCompletions = function(state, session, pos, prefix) { - // CSS completions only work with single (not nested) rulesets - return this.$completer.getCompletions("ruleset", session, pos, prefix); - }; - - this.$id = "ace/mode/less"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); diff --git a/lib/ace/mode/less_highlight_rules.js b/lib/ace/mode/less_highlight_rules.js deleted file mode 100644 index f8793e022f0..00000000000 --- a/lib/ace/mode/less_highlight_rules.js +++ /dev/null @@ -1,170 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var CssHighlightRules = require('./css_highlight_rules'); - -var LessHighlightRules = function() { - - - var keywordList = "@import|@media|@font-face|@keyframes|@-webkit-keyframes|@supports|" + - "@charset|@plugin|@namespace|@document|@page|@viewport|@-ms-viewport|" + - "or|and|when|not"; - - var keywords = keywordList.split('|'); - - var properties = CssHighlightRules.supportType.split('|'); - - var keywordMapper = this.createKeywordMapper({ - "support.constant": CssHighlightRules.supportConstant, - "keyword": keywordList, - "support.constant.color": CssHighlightRules.supportConstantColor, - "support.constant.fonts": CssHighlightRules.supportConstantFonts - }, "identifier", true); - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - var numRe = "\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))"; - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { - "start" : [ - { - token : "comment", - regex : "\\/\\/.*$" - }, - { - token : "comment", // multi line comment - regex : "\\/\\*", - next : "comment" - }, { - token : "string", // single line - regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - }, { - token : "string", // single line - regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, { - token : ["constant.numeric", "keyword"], - 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|%)" - }, { - token : "constant.numeric", // hex6 color - regex : "#[a-f0-9]{6}" - }, { - token : "constant.numeric", // hex3 color - regex : "#[a-f0-9]{3}" - }, { - token : "constant.numeric", - regex : numRe - }, { - token : ["support.function", "paren.lparen", "string", "paren.rparen"], - regex : "(url)(\\()(.*)(\\))" - }, { - token : ["support.function", "paren.lparen"], - regex : "(:extend|[a-z0-9_\\-]+)(\\()" - }, { - token : function(value) { - if (keywords.indexOf(value.toLowerCase()) > -1) - return "keyword"; - else - return "variable"; - }, - regex : "[@\\$][a-z0-9_\\-@\\$]*\\b" - }, { - token : "variable", - regex : "[@\\$]\\{[a-z0-9_\\-@\\$]*\\}" - }, { - token : function(first, second) { - if(properties.indexOf(first.toLowerCase()) > -1) { - return ["support.type.property", "text"]; - } - else { - return ["support.type.unknownProperty", "text"]; - } - }, - regex : "([a-z0-9-_]+)(\\s*:)" - }, { - token : "keyword", - regex : "&" // special case - always treat as keyword - }, { - token : keywordMapper, - regex : "\\-?[@a-z_][@a-z0-9_\\-]*" - }, { - token: "variable.language", - regex: "#[a-z0-9-_]+" - }, { - token: "variable.language", - regex: "\\.[a-z0-9-_]+" - }, { - token: "variable.language", - regex: ":[a-z_][a-z0-9-_]*" - }, { - token: "constant", - regex: "[a-z0-9-_]+" - }, { - token : "keyword.operator", - regex : "<|>|<=|>=|=|!=|-|%|\\+|\\*" - }, { - token : "paren.lparen", - regex : "[[({]" - }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" - }, { - caseInsensitive: true - } - ], - "comment" : [ - { - token : "comment", // closing comment - regex : "\\*\\/", - next : "start" - }, { - defaultToken : "comment" - } - ] - }; - this.normalizeRules(); -}; - -oop.inherits(LessHighlightRules, TextHighlightRules); - -exports.LessHighlightRules = LessHighlightRules; - -}); diff --git a/lib/ace/mode/liquid.js b/lib/ace/mode/liquid.js deleted file mode 100644 index e20124f76e9..00000000000 --- a/lib/ace/mode/liquid.js +++ /dev/null @@ -1,82 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var LiquidHighlightRules = require("./liquid_highlight_rules").LiquidHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; - -var Mode = function() { - this.HighlightRules = LiquidHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.blockComment = {start: ""}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/liquid"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/liquid_highlight_rules.js b/lib/ace/mode/liquid_highlight_rules.js deleted file mode 100644 index d609bfc8eb0..00000000000 --- a/lib/ace/mode/liquid_highlight_rules.js +++ /dev/null @@ -1,131 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; - -var LiquidHighlightRules = function() { - HtmlHighlightRules.call(this); - - // see: https://developer.mozilla.org/en/Liquid/Reference/Global_Objects - var functions = ( - // Standard Filters - "date|capitalize|downcase|upcase|first|last|join|sort|map|size|escape|" + - "escape_once|strip_html|strip_newlines|newline_to_br|replace|replace_first|" + - "truncate|truncatewords|prepend|append|minus|plus|times|divided_by|split" - ); - - var keywords = ( - // Standard Tags - "capture|endcapture|case|endcase|when|comment|endcomment|" + - "cycle|for|endfor|in|reversed|if|endif|else|elsif|include|endinclude|unless|endunless|" + - // Commonly used tags - "style|text|image|widget|plugin|marker|endmarker|tablerow|endtablerow" - ); - - var builtinVariables = 'forloop|tablerowloop'; - // "forloop\\.(length|index|index0|rindex|rindex0|first|last)|limit|offset|range" + - // "tablerowloop\\.(length|index|index0|rindex|rindex0|first|last|col|col0|"+ - // "col_first|col_last)" - - var definitions = ("assign"); - - var keywordMapper = this.createKeywordMapper({ - "variable.language": builtinVariables, - "keyword": keywords, - "support.function": functions, - "keyword.definition": definitions - }, "identifier"); - - // add liquid start tags to the HTML start tags - for (var rule in this.$rules) { - this.$rules[rule].unshift({ - token : "variable", - regex : "{%", - push : "liquid-start" - }, { - token : "variable", - regex : "{{", - push : "liquid-start" - }); - } - - this.addRules({ - "liquid-start" : [{ - token: "variable", - regex: "}}", - next: "pop" - }, { - token: "variable", - regex: "%}", - next: "pop" - }, { - token : "string", // single line - regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - }, { - token : "string", // single line - regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, { - token : "constant.numeric", // hex - regex : "0[xX][0-9a-fA-F]+\\b" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" - }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "keyword.operator", - regex : "/|\\*|\\-|\\+|=|!=|\\?\\:" - }, { - token : "paren.lparen", - regex : /[\[\({]/ - }, { - token : "paren.rparen", - regex : /[\])}]/ - }, { - token : "text", - regex : "\\s+" - }] - }); - - this.normalizeRules(); -}; -oop.inherits(LiquidHighlightRules, TextHighlightRules); - -exports.LiquidHighlightRules = LiquidHighlightRules; -}); diff --git a/lib/ace/mode/lisp.js b/lib/ace/mode/lisp.js deleted file mode 100644 index 2406080053b..00000000000 --- a/lib/ace/mode/lisp.js +++ /dev/null @@ -1,57 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var LispHighlightRules = require("./lisp_highlight_rules").LispHighlightRules; - -var Mode = function() { - this.HighlightRules = LispHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = ";"; - - this.$id = "ace/mode/lisp"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/lisp_highlight_rules.js b/lib/ace/mode/lisp_highlight_rules.js deleted file mode 100644 index 9afbf248c89..00000000000 --- a/lib/ace/mode/lisp_highlight_rules.js +++ /dev/null @@ -1,124 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * Garen J. Torikian - * - * ***** END LICENSE BLOCK ***** */ - - /* - THIS FILE WAS AUTOGENERATED BY Lisp.tmlanguage (UUID: 00D451C9-6B1D-11D9-8DFA-000D93589AF6) */ - - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var LispHighlightRules = function() { - var keywordControl = "case|do|let|loop|if|else|when"; - var keywordOperator = "eq|neq|and|or"; - var constantLanguage = "null|nil"; - var supportFunctions = "cons|car|cdr|cond|lambda|format|setq|setf|quote|eval|append|list|listp|memberp|t|load|progn"; - - var keywordMapper = this.createKeywordMapper({ - "keyword.control": keywordControl, - "keyword.operator": keywordOperator, - "constant.language": constantLanguage, - "support.function": supportFunctions - }, "identifier", true); - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = - { - "start": [ - { - token : "comment", - regex : ";.*$" - }, - { - token: ["storage.type.function-type.lisp", "text", "entity.name.function.lisp"], - regex: "(?:\\b(?:(defun|defmethod|defmacro))\\b)(\\s+)((?:\\w|\\-|\\!|\\?)*)" - }, - { - token: ["punctuation.definition.constant.character.lisp", "constant.character.lisp"], - regex: "(#)((?:\\w|[\\\\+-=<>'\"&#])+)" - }, - { - token: ["punctuation.definition.variable.lisp", "variable.other.global.lisp", "punctuation.definition.variable.lisp"], - regex: "(\\*)(\\S*)(\\*)" - }, - { - token : "constant.numeric", // hex - regex : "0[xX][0-9a-fA-F]+(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b" - }, - { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b" - }, - { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, - { - token : "string", - regex : '"(?=.)', - next : "qqstring" - } - ], - "qqstring": [ - { - token: "constant.character.escape.lisp", - regex: "\\\\." - }, - { - token : "string", - regex : '[^"\\\\]+' - }, { - token : "string", - regex : "\\\\$", - next : "qqstring" - }, { - token : "string", - regex : '"|$', - next : "start" - } - ] -}; - -}; - -oop.inherits(LispHighlightRules, TextHighlightRules); - -exports.LispHighlightRules = LispHighlightRules; -}); diff --git a/lib/ace/mode/livescript.js b/lib/ace/mode/livescript.js deleted file mode 100644 index e66c6942fe9..00000000000 --- a/lib/ace/mode/livescript.js +++ /dev/null @@ -1,232 +0,0 @@ -define(function(require, exports, module){ - var identifier, LiveScriptMode, keywordend, stringfill; - identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*'; - exports.Mode = LiveScriptMode = (function(superclass){ - var indenter, prototype = extend$((import$(LiveScriptMode, superclass).displayName = 'LiveScriptMode', LiveScriptMode), superclass).prototype, constructor = LiveScriptMode; - function LiveScriptMode(){ - var that; - this.$tokenizer = new (require('../tokenizer')).Tokenizer(LiveScriptMode.Rules); - if (that = require('../mode/matching_brace_outdent')) { - this.$outdent = new that.MatchingBraceOutdent; - } - this.$id = "ace/mode/livescript"; - this.$behaviour = new (require("./behaviour/cstyle").CstyleBehaviour)(); - } - indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$'); - prototype.getNextLineIndent = function(state, line, tab){ - var indent, tokens; - indent = this.$getIndent(line); - tokens = this.$tokenizer.getLineTokens(line, state).tokens; - if (!(tokens.length && tokens[tokens.length - 1].type === 'comment')) { - if (state === 'start' && indenter.test(line)) { - indent += tab; - } - } - return indent; - }; - prototype.lineCommentStart = "#"; - prototype.blockComment = {start: "###", end: "###"}; - prototype.checkOutdent = function(state, line, input){ - var ref$; - return (ref$ = this.$outdent) != null ? ref$.checkOutdent(line, input) : void 8; - }; - prototype.autoOutdent = function(state, doc, row){ - var ref$; - return (ref$ = this.$outdent) != null ? ref$.autoOutdent(doc, row) : void 8; - }; - return LiveScriptMode; - }(require('../mode/text').Mode)); - keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))'; - stringfill = { - defaultToken: 'string' - }; - LiveScriptMode.Rules = { - start: [ - { - token: 'keyword', - 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 - }, { - token: 'constant.language', - regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend - }, { - token: 'invalid.illegal', - regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend - }, { - token: 'language.support.class', - regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend - }, { - token: 'language.support.function', - regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend - }, { - token: 'variable.language', - regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend - }, { - token: 'identifier', - regex: identifier + '\\s*:(?![:=])' - }, { - token: 'variable', - regex: identifier - }, { - token: 'keyword.operator', - regex: '(?:\\.{3}|\\s+\\?)' - }, { - token: 'keyword.variable', - regex: '(?:@+|::|\\.\\.)', - next: 'key' - }, { - token: 'keyword.operator', - regex: '\\.\\s*', - next: 'key' - }, { - token: 'string', - regex: '\\\\\\S[^\\s,;)}\\]]*' - }, { - token: 'string.doc', - regex: '\'\'\'', - next: 'qdoc' - }, { - token: 'string.doc', - regex: '"""', - next: 'qqdoc' - }, { - token: 'string', - regex: '\'', - next: 'qstring' - }, { - token: 'string', - regex: '"', - next: 'qqstring' - }, { - token: 'string', - regex: '`', - next: 'js' - }, { - token: 'string', - regex: '<\\[', - next: 'words' - }, { - token: 'string.regex', - regex: '//', - next: 'heregex' - }, { - token: 'comment.doc', - regex: '/\\*', - next: 'comment' - }, { - token: 'comment', - regex: '#.*' - }, { - token: 'string.regex', - regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}', - next: 'key' - }, { - token: 'constant.numeric', - 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$]*)' - }, { - token: 'lparen', - regex: '[({[]' - }, { - token: 'rparen', - regex: '[)}\\]]', - next: 'key' - }, { - token: 'keyword.operator', - regex: '[\\^!|&%+\\-]+' - }, { - token: 'text', - regex: '\\s+' - } - ], - heregex: [ - { - token: 'string.regex', - regex: '.*?//[gimy$?]{0,4}', - next: 'start' - }, { - token: 'string.regex', - regex: '\\s*#{' - }, { - token: 'comment.regex', - regex: '\\s+(?:#.*)?' - }, { - defaultToken: 'string.regex' - } - ], - key: [ - { - token: 'keyword.operator', - regex: '[.?@!]+' - }, { - token: 'identifier', - regex: identifier, - next: 'start' - }, { - token: 'text', - regex: '', - next: 'start' - } - ], - comment: [ - { - token: 'comment.doc', - regex: '.*?\\*/', - next: 'start' - }, { - defaultToken: 'comment.doc' - } - ], - qdoc: [ - { - token: 'string', - regex: ".*?'''", - next: 'key' - }, stringfill - ], - qqdoc: [ - { - token: 'string', - regex: '.*?"""', - next: 'key' - }, stringfill - ], - qstring: [ - { - token: 'string', - regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'', - next: 'key' - }, stringfill - ], - qqstring: [ - { - token: 'string', - regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"', - next: 'key' - }, stringfill - ], - js: [ - { - token: 'string', - regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`', - next: 'key' - }, stringfill - ], - words: [ - { - token: 'string', - regex: '.*?\\]>', - next: 'key' - }, stringfill - ] - }; -function extend$(sub, sup){ - function fun(){} fun.prototype = (sub.superclass = sup).prototype; - (sub.prototype = new fun).constructor = sub; - if (typeof sup.extended == 'function') sup.extended(sub); - return sub; -} -function import$(obj, src){ - var own = {}.hasOwnProperty; - for (var key in src) if (own.call(src, key)) obj[key] = src[key]; - return obj; -} -}); \ No newline at end of file diff --git a/lib/ace/mode/logiql.js b/lib/ace/mode/logiql.js deleted file mode 100644 index 677d3267409..00000000000 --- a/lib/ace/mode/logiql.js +++ /dev/null @@ -1,139 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var LogiQLHighlightRules = require("./logiql_highlight_rules").LogiQLHighlightRules; -var FoldMode = require("./folding/coffee").FoldMode; -var TokenIterator = require("../token_iterator").TokenIterator; -var Range = require("../range").Range; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; - -var Mode = function() { - this.HighlightRules = LogiQLHighlightRules; - this.foldingRules = new FoldMode(); - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - if (/comment|string/.test(endState)) - return indent; - if (tokens.length && tokens[tokens.length - 1].type == "comment.single") - return indent; - - var match = line.match(); - if (/(-->|<--|<-|->|{)\s*$/.test(line)) - indent += tab; - return indent; - }; - - this.checkOutdent = function(state, line, input) { - if (this.$outdent.checkOutdent(line, input)) - return true; - - if (input !== "\n" && input !== "\r\n") - return false; - - if (!/^\s+/.test(line)) - return false; - - return true; - }; - - this.autoOutdent = function(state, doc, row) { - if (this.$outdent.autoOutdent(doc, row)) - return; - var prevLine = doc.getLine(row); - var match = prevLine.match(/^\s+/); - var column = prevLine.lastIndexOf(".") + 1; - if (!match || !row || !column) return 0; - - var line = doc.getLine(row + 1); - var startRange = this.getMatching(doc, {row: row, column: column}); - if (!startRange || startRange.start.row == row) return 0; - - column = match[0].length; - var indent = this.$getIndent(doc.getLine(startRange.start.row)); - doc.replace(new Range(row + 1, 0, row + 1, column), indent); - }; - - this.getMatching = function(session, row, column) { - if (row == undefined) - row = session.selection.lead; - if (typeof row == "object") { - column = row.column; - row = row.row; - } - - var startToken = session.getTokenAt(row, column); - var KW_START = "keyword.start", KW_END = "keyword.end"; - var tok; - if (!startToken) - return; - if (startToken.type == KW_START) { - var it = new TokenIterator(session, row, column); - it.step = it.stepForward; - } else if (startToken.type == KW_END) { - var it = new TokenIterator(session, row, column); - it.step = it.stepBackward; - } else - return; - - while (tok = it.step()) { - if (tok.type == KW_START || tok.type == KW_END) - break; - } - if (!tok || tok.type == startToken.type) - return; - - var col = it.getCurrentTokenColumn(); - var row = it.getCurrentTokenRow(); - return new Range(row, col, row, col + tok.value.length); - }; - this.$id = "ace/mode/logiql"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/logiql_highlight_rules.js b/lib/ace/mode/logiql_highlight_rules.js deleted file mode 100644 index 4a767653663..00000000000 --- a/lib/ace/mode/logiql_highlight_rules.js +++ /dev/null @@ -1,119 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* THIS FILE WAS AUTOGENERATED FROM tool\LogicBlox.tmbundle\Syntaxes\LogicBlox.tmLanguage (UUID: 59bf5022-e261-453f-b1cb-9f9fa0712413) */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var LogiQLHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { start: - [ { token: 'comment.block', - regex: '/\\*', - push: - [ { token: 'comment.block', regex: '\\*/', next: 'pop' }, - { defaultToken: 'comment.block' } ] - //A block comment. - }, - { token: 'comment.single', - regex: '//.*' - //A single line comment. - }, - { token: 'constant.numeric', - regex: '\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?[fd]?' - //An integer constant. - //Or a Real number. - }, - { token: 'string', - regex: '"', - push: - [ { token: 'string', regex: '"', next: 'pop' }, - { defaultToken: 'string' } ] - //Strings - }, - { token: 'constant.language', - regex: '\\b(true|false)\\b' - //Boolean values. - }, - { token: 'entity.name.type.logicblox', - regex: '`[a-zA-Z_:]+(\\d|\\a)*\\b' - //LogicBlox Symbol - }, - { token: 'keyword.start', regex: '->', comment: 'Constraint' }, - { token: 'keyword.start', regex: '-->', comment: 'Level 1 Constraint'}, - { token: 'keyword.start', regex: '<-', comment: 'Rule' }, - { token: 'keyword.start', regex: '<--', comment: 'Level 1 Rule' }, - { token: 'keyword.end', regex: '\\.', comment: 'Terminator' }, - { token: 'keyword.other', regex: '!', comment: 'Negation' }, - { token: 'keyword.other', regex: ',', comment: 'Conjunction' }, - { token: 'keyword.other', regex: ';', comment: 'Disjunction' }, - { token: 'keyword.operator', regex: '<=|>=|!=|<|>', comment: 'Equality'}, - { token: 'keyword.other', regex: '@', comment: 'Equality' }, - { token: 'keyword.operator', regex: '\\+|-|\\*|/', comment: 'Arithmetic operations'}, - { token: 'keyword', regex: '::', comment: 'Colon colon' }, - { token: 'support.function', - regex: '\\b(agg\\s*<<)', - push: - [ { include: '$self' }, - { token: 'support.function', - regex: '>>', - next: 'pop' } ] - //Aggregations - }, - { token: 'storage.modifier', - regex: '\\b(lang:[\\w:]*)' - //All the lang system predicates - }, - { token: [ 'storage.type', 'text' ], - regex: '(export|sealed|clauses|block|alias|alias_all)(\\s*\\()(?=`)' - //Module keywords - }, - { token: 'entity.name', - regex: '[a-zA-Z_][a-zA-Z_0-9:]*(@prev|@init|@final)?(?=(\\(|\\[))' - //A predicate name. - }, - { token: 'variable.parameter', - regex: '([a-zA-Z][a-zA-Z_0-9]*|_)\\s*(?=(,|\\.|<-|->|\\)|\\]|=))' - //A variable to a functional predicate. - } ] }; - - this.normalizeRules(); -}; - -oop.inherits(LogiQLHighlightRules, TextHighlightRules); - -exports.LogiQLHighlightRules = LogiQLHighlightRules; -}); diff --git a/lib/ace/mode/logiql_test.js b/lib/ace/mode/logiql_test.js deleted file mode 100644 index 169fe1696b0..00000000000 --- a/lib/ace/mode/logiql_test.js +++ /dev/null @@ -1,98 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -if (typeof process !== "undefined") { - require("amd-loader"); -} - -define(function(require, exports, module) { -"use strict"; - -var EditSession = require("../edit_session").EditSession; -var LogiQLMode = require("./logiql").Mode; -var assert = require("../test/assertions"); - -module.exports = { - setUp : function() { - this.mode = new LogiQLMode(); - }, - - "test: toggle comment lines should prepend '//' to each line" : function() { - var session = new EditSession([" abc", "cde", "fg"]); - - this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal(["// abc", "// cde", "fg"].join("\n"), session.toString()); - }, - - "test: auto indent after ->" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", "parent(a, b) ->", " ")); - }, - - "test: auto indent after <--" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", "foo <-- ", " ")); - }, - - "test: no auto indent in multi line comment" : function() { - assert.equal("", this.mode.getNextLineIndent("start", "/* -->", " ")); - assert.equal(" ", this.mode.getNextLineIndent("start", " /* ->", " ")); - assert.equal(" ", this.mode.getNextLineIndent("comment.block", " abcd", " ")); - }, - - "test: no auto indent after -> in single line comment" : function() { - assert.equal("", this.mode.getNextLineIndent("start", "//->", " ")); - assert.equal(" ", this.mode.getNextLineIndent("start", " //->", " ")); - }, - - "test: trigger outdent if line ends with ." : function() { - assert.ok(this.mode.checkOutdent("start", " ", "\n")); - assert.ok(this.mode.checkOutdent("start", " a ", "\r\n")); - assert.ok(!this.mode.checkOutdent("start", "", "}")); - assert.ok(!this.mode.checkOutdent("start", " ", "a }")); - assert.ok(!this.mode.checkOutdent("start", " }", "}")); - }, - - "test: auto outdent should indent the line with the same indent as the line with the matching ->" : function() { - var session = new EditSession([" bar (a, b) ->", " foo(a)[1.2]", " bla.", " "], new LogiQLMode()); - this.mode.autoOutdent("start", session, 2); - assert.equal(" ", session.getLine(3)); - }, - - "test: no auto outdent if no matching brace is found" : function() { - var session = new EditSession([" bar (a, b) ->", " foo(a)[1.2].", " bla.", " "], new LogiQLMode()); - this.mode.autoOutdent("start", session, 2); - assert.equal(" ", session.getLine(3)); - } -}; - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("asyncjs").test.testcase(module.exports).exec(); -} diff --git a/lib/ace/mode/lsl.js b/lib/ace/mode/lsl.js deleted file mode 100644 index 14a67244ce8..00000000000 --- a/lib/ace/mode/lsl.js +++ /dev/null @@ -1,92 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2013, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var Rules = require("./lsl_highlight_rules").LSLHighlightRules; -var Outdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; -var TextMode = require("./text").Mode; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; -var oop = require("../lib/oop"); - -var Mode = function() { - this.HighlightRules = Rules; - this.$outdent = new Outdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = ["//"]; - - this.blockComment = { - start: "/*", - end: "*/" - }; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - - if (tokens.length && tokens[tokens.length-1].type === "comment.block.lsl") { - return indent; - } - - if (state === "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/lsl"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/lua.js b/lib/ace/mode/lua.js deleted file mode 100644 index 51c9304c557..00000000000 --- a/lib/ace/mode/lua.js +++ /dev/null @@ -1,169 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var LuaHighlightRules = require("./lua_highlight_rules").LuaHighlightRules; -var LuaFoldMode = require("./folding/lua").FoldMode; -var Range = require("../range").Range; -var WorkerClient = require("../worker/worker_client").WorkerClient; - -var Mode = function() { - this.HighlightRules = LuaHighlightRules; - - this.foldingRules = new LuaFoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "--"; - this.blockComment = {start: "--[", end: "]--"}; - - var indentKeywords = { - "function": 1, - "then": 1, - "do": 1, - "else": 1, - "elseif": 1, - "repeat": 1, - "end": -1, - "until": -1 - }; - var outdentKeywords = [ - "else", - "elseif", - "end", - "until" - ]; - - function getNetIndentLevel(tokens) { - var level = 0; - // Support single-line blocks by decrementing the indent level if - // an ending token is found - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - if (token.type == "keyword") { - if (token.value in indentKeywords) { - level += indentKeywords[token.value]; - } - } else if (token.type == "paren.lparen") { - level += token.value.length; - } else if (token.type == "paren.rparen") { - level -= token.value.length; - } - } - // Limit the level to +/- 1 since usually users only indent one level - // at a time regardless of the logical nesting level - if (level < 0) { - return -1; - } else if (level > 0) { - return 1; - } else { - return 0; - } - } - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - var level = 0; - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - - if (state == "start") { - level = getNetIndentLevel(tokens); - } - if (level > 0) { - return indent + tab; - } else if (level < 0 && indent.substr(indent.length - tab.length) == tab) { - // Don't do a next-line outdent if we're going to do a real outdent of this line - if (!this.checkOutdent(state, line, "\n")) { - return indent.substr(0, indent.length - tab.length); - } - } - return indent; - }; - - this.checkOutdent = function(state, line, input) { - if (input != "\n" && input != "\r" && input != "\r\n") - return false; - - if (line.match(/^\s*[\)\}\]]$/)) - return true; - - var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens; - - if (!tokens || !tokens.length) - return false; - - return (tokens[0].type == "keyword" && outdentKeywords.indexOf(tokens[0].value) != -1); - }; - - this.autoOutdent = function(state, session, row) { - var prevLine = session.getLine(row - 1); - var prevIndent = this.$getIndent(prevLine).length; - var prevTokens = this.getTokenizer().getLineTokens(prevLine, "start").tokens; - var tabLength = session.getTabString().length; - var expectedIndent = prevIndent + tabLength * getNetIndentLevel(prevTokens); - var curIndent = this.$getIndent(session.getLine(row)).length; - if (curIndent <= expectedIndent) { - // User already outdented // - return; - } - session.outdentRows(new Range(row, 0, row + 2, 0)); - }; - - this.createWorker = function(session) { - var worker = new WorkerClient(["ace"], "ace/mode/lua_worker", "Worker"); - worker.attachToDocument(session.getDocument()); - - worker.on("annotate", function(e) { - session.setAnnotations(e.data); - }); - - worker.on("terminate", function() { - session.clearAnnotations(); - }); - - return worker; - }; - - this.$id = "ace/mode/lua"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); - - diff --git a/lib/ace/mode/lua/luaparse.js b/lib/ace/mode/lua/luaparse.js index 3339f6e54b5..c4e644c80f0 100644 --- a/lib/ace/mode/lua/luaparse.js +++ b/lib/ace/mode/lua/luaparse.js @@ -1,14 +1,14 @@ define(function(require, exports, module) { -/*global exports:true module:true require:true define:true global:true */ +/* global exports:true, module:true, require:true, define:true, global:true */ (function (root, name, factory) { factory(exports) }(this, 'luaparse', function (exports) { 'use strict'; - exports.version = '0.1.4'; + exports.version = "0.3.1"; - var input, options, length; + var input, options, length, features, encodingMode; // Options can be set either globally on the parser object through // defaultOptions, or during the parse call. @@ -26,6 +26,112 @@ define(function(require, exports, module) { // Store the start and end character locations on each syntax node as // `range: [start, end]`. , ranges: false + // A callback which will be invoked when a syntax node has been completed. + // The node which has been created will be passed as the only parameter. + , onCreateNode: null + // A callback which will be invoked when a new scope is created. + , onCreateScope: null + // A callback which will be invoked when the current scope is destroyed. + , onDestroyScope: null + // A callback which will be invoked when a local variable is declared in the current scope. + // The variable's name will be passed as the only parameter + , onLocalDeclaration: null + // The version of Lua targeted by the parser (string; allowed values are + // '5.1', '5.2', '5.3'). + , luaVersion: '5.3' + // Encoding mode: how to interpret code units higher than U+007F in input + , encodingMode: 'none' + }; + + function encodeUTF8(codepoint, highMask) { + highMask = highMask || 0; + + if (codepoint < 0x80) { + return String.fromCharCode(codepoint); + } else if (codepoint < 0x800) { + return String.fromCharCode( + highMask | 0xc0 | (codepoint >> 6) , + highMask | 0x80 | ( codepoint & 0x3f) + ); + } else if (codepoint < 0x10000) { + return String.fromCharCode( + highMask | 0xe0 | (codepoint >> 12) , + highMask | 0x80 | ((codepoint >> 6) & 0x3f), + highMask | 0x80 | ( codepoint & 0x3f) + ); + } else /* istanbul ignore else */ if (codepoint < 0x110000) { + return String.fromCharCode( + highMask | 0xf0 | (codepoint >> 18) , + highMask | 0x80 | ((codepoint >> 12) & 0x3f), + highMask | 0x80 | ((codepoint >> 6) & 0x3f), + highMask | 0x80 | ( codepoint & 0x3f) + ); + } else { + // TODO: Lua 5.4 allows up to six-byte sequences, as in UTF-8:1993 + return null; + } + } + + function toHex(num, digits) { + var result = num.toString(16); + while (result.length < digits) + result = '0' + result; + return result; + } + + function checkChars(rx) { + return function (s) { + var m = rx.exec(s); + if (!m) + return s; + raise(null, errors.invalidCodeUnit, toHex(m[0].charCodeAt(0), 4).toUpperCase()); + }; + } + + var encodingModes = { + // `pseudo-latin1` encoding mode: assume the input was decoded with the latin1 encoding + // WARNING: latin1 does **NOT** mean cp1252 here like in the bone-headed WHATWG standard; + // it means true ISO/IEC 8859-1 identity-mapped to Basic Latin and Latin-1 Supplement blocks + 'pseudo-latin1': { + fixup: checkChars(/[^\x00-\xff]/), + encodeByte: function (value) { + if (value === null) + return ''; + return String.fromCharCode(value); + }, + encodeUTF8: function (codepoint) { + return encodeUTF8(codepoint); + }, + }, + + // `x-user-defined` encoding mode: assume the input was decoded with the WHATWG `x-user-defined` encoding + 'x-user-defined': { + fixup: checkChars(/[^\x00-\x7f\uf780-\uf7ff]/), + encodeByte: function (value) { + if (value === null) + return ''; + if (value >= 0x80) + return String.fromCharCode(value | 0xf700); + return String.fromCharCode(value); + }, + encodeUTF8: function (codepoint) { + return encodeUTF8(codepoint, 0xf700); + } + }, + + // `none` encoding mode: disregard intrepretation of string literals, leave identifiers as-is + 'none': { + discardStrings: true, + fixup: function (s) { + return s; + }, + encodeByte: function (value) { + return ''; + }, + encodeUTF8: function (codepoint) { + return ''; + } + } }; // The available tokens expressed as enum flags so they can be checked with @@ -45,11 +151,26 @@ define(function(require, exports, module) { // will be different in some situations. var errors = exports.errors = { - unexpected: 'Unexpected %1 \'%2\' near \'%3\'' + unexpected: 'unexpected %1 \'%2\' near \'%3\'' + , unexpectedEOF: 'unexpected symbol near \'\'' , expected: '\'%1\' expected near \'%2\'' , expectedToken: '%1 expected near \'%2\'' , unfinishedString: 'unfinished string near \'%1\'' , malformedNumber: 'malformed number near \'%1\'' + , decimalEscapeTooLarge: 'decimal escape too large near \'%1\'' + , invalidEscape: 'invalid escape sequence near \'%1\'' + , hexadecimalDigitExpected: 'hexadecimal digit expected near \'%1\'' + , braceExpected: 'missing \'%1\' near \'%2\'' + , tooLargeCodepoint: 'UTF-8 value too large near \'%1\'' + , unfinishedLongString: 'unfinished long string (starting at line %1) near \'%2\'' + , unfinishedLongComment: 'unfinished long comment (starting at line %1) near \'%2\'' + , ambiguousSyntax: 'ambiguous syntax (function call x new statement) near \'%1\'' + , noLoopToBreak: 'no loop to break near \'%1\'' + , labelAlreadyDefined: 'label \'%1\' already defined on line %2' + , labelNotVisible: 'no visible label \'%1\' for ' + , gotoJumpInLocalScope: ' jumps into the scope of local \'%2\'' + , cannotUseVararg: 'cannot use \'...\' outside a vararg function near \'%1\'' + , invalidCodeUnit: 'code unit U+%1 is not allowed in the current encoding mode' }; // ### Abstract Syntax Tree @@ -320,31 +441,38 @@ define(function(require, exports, module) { if (trackLocations) { var location = locations.pop(); location.complete(); - if (options.locations) node.loc = location.loc; - if (options.ranges) node.range = location.range; + location.bless(node); } + if (options.onCreateNode) options.onCreateNode(node); return node; } - // Helpers // ------- var slice = Array.prototype.slice , toString = Object.prototype.toString - , indexOf = function indexOf(array, element) { - for (var i = 0, length = array.length; i < length; i++) { - if (array[i] === element) return i; - } - return -1; + ; + + var indexOf = /* istanbul ignore next */ function (array, element) { + for (var i = 0, length = array.length; i < length; ++i) { + if (array[i] === element) return i; + } + return -1; + }; + + /* istanbul ignore else */ + if (Array.prototype.indexOf) + indexOf = function (array, element) { + return array.indexOf(element); }; // Iterate through an array of objects and return the index of an object // with a matching property. function indexOfObject(array, property, element) { - for (var i = 0, length = array.length; i < length; i++) { + for (var i = 0, length = array.length; i < length; ++i) { if (array[i][property] === element) return i; } return -1; @@ -361,34 +489,53 @@ define(function(require, exports, module) { function sprintf(format) { var args = slice.call(arguments, 1); format = format.replace(/%(\d)/g, function (match, index) { - return '' + args[index - 1] || ''; + return '' + args[index - 1] || /* istanbul ignore next */ ''; }); return format; } - // Returns a new object with the properties from all objectes passed as - // arguments. Last argument takes precedence. - // - // Example: - // - // this.options = extend(options, { output: false }); + // Polyfill for `Object.assign`. - function extend() { - var args = slice.call(arguments) - , dest = {} + var assign = /* istanbul ignore next */ function (dest) { + var args = slice.call(arguments, 1) , src, prop; - for (var i = 0, length = args.length; i < length; i++) { + for (var i = 0, length = args.length; i < length; ++i) { src = args[i]; - for (prop in src) if (src.hasOwnProperty(prop)) { - dest[prop] = src[prop]; - } + for (prop in src) + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(src, prop)) { + dest[prop] = src[prop]; + } } + return dest; - } + }; + + /* istanbul ignore else */ + if (Object.assign) + assign = Object.assign; // ### Error functions + exports.SyntaxError = SyntaxError; + + // XXX: Eliminate this function and change the error type to be different from SyntaxError. + // This will unfortunately be a breaking change, because some downstream users depend + // on the error thrown being an instance of SyntaxError. For example, the Ace editor: + // + + function fixupError(e) { + /* istanbul ignore if */ + if (!Object.create) + return e; + return Object.create(e, { + 'line': { 'writable': true, value: e.line }, + 'index': { 'writable': true, value: e.index }, + 'column': { 'writable': true, value: e.column } + }); + } + // #### Raise an exception. // // Raise an exception by passing a token, a string format and its paramters. @@ -406,22 +553,29 @@ define(function(require, exports, module) { var message = sprintf.apply(null, slice.call(arguments, 1)) , error, col; - if ('undefined' !== typeof token.line) { - col = token.range[0] - token.lineStart; - error = new SyntaxError(sprintf('[%1:%2] %3', token.line, col, message)); - error.line = token.line; - error.index = token.range[0]; - error.column = col; - } else { + if (token === null || typeof token.line === 'undefined') { col = index - lineStart + 1; - error = new SyntaxError(sprintf('[%1:%2] %3', line, col, message)); + error = fixupError(new SyntaxError(sprintf('[%1:%2] %3', line, col, message))); error.index = index; error.line = line; error.column = col; + } else { + col = token.range[0] - token.lineStart; + error = fixupError(new SyntaxError(sprintf('[%1:%2] %3', token.line, col, message))); + error.line = token.line; + error.index = token.range[0]; + error.column = col; } throw error; } + function tokenValue(token) { + var raw = input.slice(token.range[0], token.range[1]); + if (raw) + return raw; + return token.value; + } + // #### Raise an unexpected token error. // // Example: @@ -430,7 +584,7 @@ define(function(require, exports, module) { // raiseUnexpectedToken('', token); function raiseUnexpectedToken(type, token) { - raise(token, errors.expectedToken, type, token.value); + raise(token, errors.expectedToken, type, tokenValue(token)); } // #### Raise a general unexpected error @@ -446,8 +600,8 @@ define(function(require, exports, module) { // // If there's no token in the buffer it means we have reached . - function unexpected(found, near) { - if ('undefined' === typeof near) near = lookahead.value; + function unexpected(found) { + var near = tokenValue(lookahead); if ('undefined' !== typeof found.type) { var type; switch (found.type) { @@ -459,8 +613,10 @@ define(function(require, exports, module) { case BooleanLiteral: type = 'boolean'; break; case NilLiteral: return raise(found, errors.unexpected, 'symbol', 'nil', near); + case EOF: + return raise(found, errors.unexpectedEOF); } - return raise(found, errors.unexpected, type, found.value, near); + return raise(found, errors.unexpected, type, tokenValue(found), near); } return raise(found, errors.unexpected, 'symbol', found, near); } @@ -523,9 +679,8 @@ define(function(require, exports, module) { case 39: case 34: // '" return scanStringLiteral(); - // 0-9 case 48: case 49: case 50: case 51: case 52: case 53: - case 54: case 55: case 56: case 57: + case 54: case 55: case 56: case 57: // 0-9 return scanNumericLiteral(); case 46: // . @@ -542,19 +697,26 @@ define(function(require, exports, module) { return scanPunctuator('='); case 62: // > + if (features.bitwiseOperators) + if (62 === next) return scanPunctuator('>>'); if (61 === next) return scanPunctuator('>='); return scanPunctuator('>'); case 60: // < + if (features.bitwiseOperators) + if (60 === next) return scanPunctuator('<<'); if (61 === next) return scanPunctuator('<='); return scanPunctuator('<'); case 126: // ~ if (61 === next) return scanPunctuator('~='); + if (!features.bitwiseOperators) + break; return scanPunctuator('~'); case 58: // : - if (58 === next) return scanPunctuator('::'); + if (features.labels) + if (58 === next) return scanPunctuator('::'); return scanPunctuator(':'); case 91: // [ @@ -562,9 +724,20 @@ define(function(require, exports, module) { if (91 === next || 61 === next) return scanLongStringLiteral(); return scanPunctuator('['); - // \* / ^ % , { } ] ( ) ; # - + - case 42: case 47: case 94: case 37: case 44: case 123: case 125: - case 93: case 40: case 41: case 59: case 35: case 45: case 43: case 38: case 124: + case 47: // / + // Check for integer division op (//) + if (features.integerDivision) + if (47 === next) return scanPunctuator('//'); + return scanPunctuator('/'); + + case 38: case 124: // & | + if (!features.bitwiseOperators) + break; + + /* fall through */ + case 42: case 94: case 37: case 44: case 123: case 125: + case 93: case 40: case 41: case 59: case 35: case 45: + case 43: // * ^ % , { } ] ( ) ; # - + return scanPunctuator(input.charAt(index)); } @@ -572,18 +745,31 @@ define(function(require, exports, module) { } // Whitespace has no semantic meaning in lua so simply skip ahead while - // tracking the encounted newlines. Newlines are also tracked in all - // token functions where multiline values are allowed. + // tracking the encounted newlines. Any kind of eol sequence is counted as a + // single line. + + function consumeEOL() { + var charCode = input.charCodeAt(index) + , peekCharCode = input.charCodeAt(index + 1); + + if (isLineTerminator(charCode)) { + // Count \n\r and \r\n as one newline. + if (10 === charCode && 13 === peekCharCode) ++index; + if (13 === charCode && 10 === peekCharCode) ++index; + ++line; + lineStart = ++index; + + return true; + } + return false; + } function skipWhiteSpace() { while (index < length) { var charCode = input.charCodeAt(index); if (isWhiteSpace(charCode)) { - index++; - } else if (isLineTerminator(charCode)) { - line++; - lineStart = ++index; - } else { + ++index; + } else if (!consumeEOL()) { break; } } @@ -599,7 +785,7 @@ define(function(require, exports, module) { // Slicing the input string is prefered before string concatenation in a // loop for performance reasons. while (isIdentifierPart(input.charCodeAt(++index))); - value = input.slice(tokenStart, index); + value = encodingMode.fixup(input.slice(tokenStart, index)); // Decide on the token type and possibly cast the value. if (isKeyword(value)) { @@ -654,31 +840,44 @@ define(function(require, exports, module) { function scanStringLiteral() { var delimiter = input.charCodeAt(index++) + , beginLine = line + , beginLineStart = lineStart , stringStart = index - , string = '' + , string = encodingMode.discardStrings ? null : '' , charCode; - while (index < length) { + for (;;) { charCode = input.charCodeAt(index++); if (delimiter === charCode) break; - if (92 === charCode) { // \ - string += input.slice(stringStart, index - 1) + readEscapeSequence(); - stringStart = index; - } // EOF or `\n` terminates a string literal. If we haven't found the // ending delimiter by now, raise an exception. - else if (index >= length || isLineTerminator(charCode)) { + if (index > length || isLineTerminator(charCode)) { string += input.slice(stringStart, index - 1); - raise({}, errors.unfinishedString, string + String.fromCharCode(charCode)); + raise(null, errors.unfinishedString, input.slice(tokenStart, index - 1)); + } + if (92 === charCode) { // backslash + if (!encodingMode.discardStrings) { + var beforeEscape = input.slice(stringStart, index - 1); + string += encodingMode.fixup(beforeEscape); + } + var escapeValue = readEscapeSequence(); + if (!encodingMode.discardStrings) + string += escapeValue; + stringStart = index; } } - string += input.slice(stringStart, index - 1); + if (!encodingMode.discardStrings) { + string += encodingMode.encodeByte(null); + string += encodingMode.fixup(input.slice(stringStart, index - 1)); + } return { type: StringLiteral , value: string - , line: line - , lineStart: lineStart + , line: beginLine + , lineStart: beginLineStart + , lastLine: line + , lastLineStart: lineStart , range: [tokenStart, index] }; } @@ -688,15 +887,19 @@ define(function(require, exports, module) { // exception. function scanLongStringLiteral() { - var string = readLongString(); + var beginLine = line + , beginLineStart = lineStart + , string = readLongString(false); // Fail if it's not a multiline literal. - if (false === string) raise(token, errors.expected, '[', token.value); + if (false === string) raise(token, errors.expected, '[', tokenValue(token)); return { type: StringLiteral - , value: string - , line: line - , lineStart: lineStart + , value: encodingMode.discardStrings ? null : encodingMode.fixup(string) + , line: beginLine + , lineStart: beginLineStart + , lastLine: line + , lastLineStart: lineStart , range: [tokenStart, index] }; } @@ -711,18 +914,71 @@ define(function(require, exports, module) { var character = input.charAt(index) , next = input.charAt(index + 1); - var value = ('0' === character && 'xX'.indexOf(next || null) >= 0) ? + var literal = ('0' === character && 'xX'.indexOf(next || null) >= 0) ? readHexLiteral() : readDecLiteral(); + var foundImaginaryUnit = readImaginaryUnitSuffix() + , foundInt64Suffix = readInt64Suffix(); + + if (foundInt64Suffix && (foundImaginaryUnit || literal.hasFractionPart)) { + raise(null, errors.malformedNumber, input.slice(tokenStart, index)); + } + return { type: NumericLiteral - , value: value + , value: literal.value , line: line , lineStart: lineStart , range: [tokenStart, index] }; } + function readImaginaryUnitSuffix() { + if (!features.imaginaryNumbers) return; + + // Imaginary unit number suffix is optional. + // See http://luajit.org/ext_ffi_api.html#literals + if ('iI'.indexOf(input.charAt(index) || null) >= 0) { + ++index; + return true; + } else { + return false; + } + } + + function readInt64Suffix() { + if (!features.integerSuffixes) return; + + // Int64/uint64 number suffix is optional. + // See http://luajit.org/ext_ffi_api.html#literals + + if ('uU'.indexOf(input.charAt(index) || null) >= 0) { + ++index; + if ('lL'.indexOf(input.charAt(index) || null) >= 0) { + ++index; + if ('lL'.indexOf(input.charAt(index) || null) >= 0) { + ++index; + return 'ULL'; + } else { + // UL but no L + raise(null, errors.malformedNumber, input.slice(tokenStart, index)); + } + } else { + // U but no L + raise(null, errors.malformedNumber, input.slice(tokenStart, index)); + } + } else if ('lL'.indexOf(input.charAt(index) || null) >= 0) { + ++index; + if ('lL'.indexOf(input.charAt(index) || null) >= 0) { + ++index; + return 'LL'; + } else { + // First L but no second L + raise(null, errors.malformedNumber, input.slice(tokenStart, index)); + } + } + } + // Lua hexadecimals have an optional fraction part and an optional binary // exoponent part. These are not included in JavaScript so we will compute // all three parts separately and then sum them up at the end of the function @@ -743,17 +999,19 @@ define(function(require, exports, module) { // A minimum of one hex digit is required. if (!isHexDigit(input.charCodeAt(index))) - raise({}, errors.malformedNumber, input.slice(tokenStart, index)); + raise(null, errors.malformedNumber, input.slice(tokenStart, index)); - while (isHexDigit(input.charCodeAt(index))) index++; + while (isHexDigit(input.charCodeAt(index))) ++index; // Convert the hexadecimal digit to base 10. digit = parseInt(input.slice(digitStart, index), 16); - // Fraction part i optional. + // Fraction part is optional. + var foundFraction = false; if ('.' === input.charAt(index)) { + foundFraction = true; fractionStart = ++index; - while (isHexDigit(input.charCodeAt(index))) index++; + while (isHexDigit(input.charCodeAt(index))) ++index; fraction = input.slice(fractionStart, index); // Empty fraction parts should default to 0, others should be converted @@ -763,8 +1021,10 @@ define(function(require, exports, module) { } // Binary exponents are optional + var foundBinaryExponent = false; if ('pP'.indexOf(input.charAt(index) || null) >= 0) { - index++; + foundBinaryExponent = true; + ++index; // Sign part is optional and defaults to 1 (positive). if ('+-'.indexOf(input.charAt(index) || null) >= 0) @@ -774,16 +1034,19 @@ define(function(require, exports, module) { // The binary exponent sign requires a decimal digit. if (!isDecDigit(input.charCodeAt(index))) - raise({}, errors.malformedNumber, input.slice(tokenStart, index)); + raise(null, errors.malformedNumber, input.slice(tokenStart, index)); - while (isDecDigit(input.charCodeAt(index))) index++; + while (isDecDigit(input.charCodeAt(index))) ++index; binaryExponent = input.slice(exponentStart, index); // Calculate the binary exponent of the number. binaryExponent = Math.pow(2, binaryExponent * binarySign); } - return (digit + fraction) * binaryExponent; + return { + value: (digit + fraction) * binaryExponent, + hasFractionPart: foundFraction || foundBinaryExponent + }; } // Decimal numbers are exactly the same in Lua and in JavaScript, because of @@ -791,63 +1054,136 @@ define(function(require, exports, module) { // functions. function readDecLiteral() { - while (isDecDigit(input.charCodeAt(index))) index++; + while (isDecDigit(input.charCodeAt(index))) ++index; // Fraction part is optional + var foundFraction = false; if ('.' === input.charAt(index)) { - index++; + foundFraction = true; + ++index; // Fraction part defaults to 0 - while (isDecDigit(input.charCodeAt(index))) index++; + while (isDecDigit(input.charCodeAt(index))) ++index; } + // Exponent part is optional. + var foundExponent = false; if ('eE'.indexOf(input.charAt(index) || null) >= 0) { - index++; + foundExponent = true; + ++index; // Sign part is optional. - if ('+-'.indexOf(input.charAt(index) || null) >= 0) index++; + if ('+-'.indexOf(input.charAt(index) || null) >= 0) ++index; // An exponent is required to contain at least one decimal digit. if (!isDecDigit(input.charCodeAt(index))) - raise({}, errors.malformedNumber, input.slice(tokenStart, index)); + raise(null, errors.malformedNumber, input.slice(tokenStart, index)); - while (isDecDigit(input.charCodeAt(index))) index++; + while (isDecDigit(input.charCodeAt(index))) ++index; } - return parseFloat(input.slice(tokenStart, index)); + return { + value: parseFloat(input.slice(tokenStart, index)), + hasFractionPart: foundFraction || foundExponent + }; } + function readUnicodeEscapeSequence() { + var sequenceStart = index++; - // Translate escape sequences to the actual characters. + if (input.charAt(index++) !== '{') + raise(null, errors.braceExpected, '{', '\\' + input.slice(sequenceStart, index)); + if (!isHexDigit(input.charCodeAt(index))) + raise(null, errors.hexadecimalDigitExpected, '\\' + input.slice(sequenceStart, index)); + + while (input.charCodeAt(index) === 0x30) ++index; + var escStart = index; + + while (isHexDigit(input.charCodeAt(index))) { + ++index; + if (index - escStart > 6) + raise(null, errors.tooLargeCodepoint, '\\' + input.slice(sequenceStart, index)); + } + + var b = input.charAt(index++); + if (b !== '}') { + if ((b === '"') || (b === "'")) + raise(null, errors.braceExpected, '}', '\\' + input.slice(sequenceStart, index--)); + else + raise(null, errors.hexadecimalDigitExpected, '\\' + input.slice(sequenceStart, index)); + } + + var codepoint = parseInt(input.slice(escStart, index - 1) || '0', 16); + var frag = '\\' + input.slice(sequenceStart, index); + + if (codepoint > 0x10ffff) { + raise(null, errors.tooLargeCodepoint, frag); + } + return encodingMode.encodeUTF8(codepoint, frag); + } + + // Translate escape sequences to the actual characters. function readEscapeSequence() { var sequenceStart = index; switch (input.charAt(index)) { // Lua allow the following escape sequences. - // We don't escape the bell sequence. - case 'n': index++; return '\n'; - case 'r': index++; return '\r'; - case 't': index++; return '\t'; - case 'v': index++; return '\x0B'; - case 'b': index++; return '\b'; - case 'f': index++; return '\f'; - // Skips the following span of white-space. - case 'z': index++; skipWhiteSpace(); return ''; - // Byte representation should for now be returned as is. - case 'x': - // \xXX, where XX is a sequence of exactly two hexadecimal digits - if (isHexDigit(input.charCodeAt(index + 1)) && - isHexDigit(input.charCodeAt(index + 2))) { - index += 3; - // Return it as is, without translating the byte. - return '\\' + input.slice(sequenceStart, index); - } - return '\\' + input.charAt(index++); - default: + case 'a': ++index; return '\x07'; + case 'n': ++index; return '\n'; + case 'r': ++index; return '\r'; + case 't': ++index; return '\t'; + case 'v': ++index; return '\x0b'; + case 'b': ++index; return '\b'; + case 'f': ++index; return '\f'; + + // Backslash at the end of the line. We treat all line endings as equivalent, + // and as representing the [LF] character (code 10). Lua 5.1 through 5.3 + // have been verified to behave the same way. + case '\r': + case '\n': + consumeEOL(); + return '\n'; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': // \ddd, where ddd is a sequence of up to three decimal digits. - if (isDecDigit(input.charCodeAt(index))) { - while (isDecDigit(input.charCodeAt(++index))); - return '\\' + input.slice(sequenceStart, index); + while (isDecDigit(input.charCodeAt(index)) && index - sequenceStart < 3) ++index; + + var frag = input.slice(sequenceStart, index); + var ddd = parseInt(frag, 10); + if (ddd > 255) { + raise(null, errors.decimalEscapeTooLarge, '\\' + ddd); + } + return encodingMode.encodeByte(ddd, '\\' + frag); + + case 'z': + if (features.skipWhitespaceEscape) { + ++index; + skipWhiteSpace(); + return ''; } - // Simply return the \ as is, it's not escaping any sequence. + break; + + case 'x': + if (features.hexEscapes) { + // \xXX, where XX is a sequence of exactly two hexadecimal digits + if (isHexDigit(input.charCodeAt(index + 1)) && + isHexDigit(input.charCodeAt(index + 2))) { + index += 3; + return encodingMode.encodeByte(parseInt(input.slice(sequenceStart + 1, index), 16), '\\' + input.slice(sequenceStart, index)); + } + raise(null, errors.hexadecimalDigitExpected, '\\' + input.slice(sequenceStart, index + 2)); + } + break; + + case 'u': + if (features.unicodeEscapes) + return readUnicodeEscapeSequence(); + break; + + case '\\': case '"': case "'": return input.charAt(index++); } + + if (features.strictEscapes) + raise(null, errors.invalidEscape, '\\' + input.slice(sequenceStart, index + 1)); + return input.charAt(index++); } // Comments begin with -- after which it will be decided if they are @@ -868,7 +1204,7 @@ define(function(require, exports, module) { , lineComment = line; if ('[' === character) { - content = readLongString(); + content = readLongString(true); // This wasn't a multiline comment after all. if (false === content) content = character; else isLong = true; @@ -877,7 +1213,7 @@ define(function(require, exports, module) { if (!isLong) { while (index < length) { if (isLineTerminator(input.charCodeAt(index))) break; - index++; + ++index; } if (options.comments) content = input.slice(commentStart, index); } @@ -896,6 +1232,7 @@ define(function(require, exports, module) { if (options.ranges) { node.range = [tokenStart, index]; } + if (options.onCreateNode) options.onCreateNode(node); comments.push(node); } } @@ -903,55 +1240,54 @@ define(function(require, exports, module) { // Read a multiline string by calculating the depth of `=` characters and // then appending until an equal depth is found. - function readLongString() { + function readLongString(isComment) { var level = 0 , content = '' , terminator = false - , character, stringStart; + , character, stringStart, firstLine = line; - index++; // [ + ++index; // [ // Calculate the depth of the comment. - while ('=' === input.charAt(index + level)) level++; + while ('=' === input.charAt(index + level)) ++level; // Exit, this is not a long string afterall. if ('[' !== input.charAt(index + level)) return false; index += level + 1; // If the first character is a newline, ignore it and begin on next line. - if (isLineTerminator(input.charCodeAt(index))) { - line++; - lineStart = index++; - } + if (isLineTerminator(input.charCodeAt(index))) consumeEOL(); stringStart = index; while (index < length) { - character = input.charAt(index++); + // To keep track of line numbers run the `consumeEOL()` which increments + // its counter. + while (isLineTerminator(input.charCodeAt(index))) consumeEOL(); - // We have to keep track of newlines as `skipWhiteSpace()` does not get - // to scan this part. - if (isLineTerminator(character.charCodeAt(0))) { - line++; - lineStart = index; - } + character = input.charAt(index++); // Once the delimiter is found, iterate through the depth count and see // if it matches. if (']' === character) { terminator = true; - for (var i = 0; i < level; i++) { + for (var i = 0; i < level; ++i) { if ('=' !== input.charAt(index + i)) terminator = false; } if (']' !== input.charAt(index + level)) terminator = false; } // We reached the end of the multiline string. Get out now. - if (terminator) break; + if (terminator) { + content += input.slice(stringStart, index - 1); + index += level + 1; + return content; + } } - content += input.slice(stringStart, index - 1); - index += level + 1; - return content; + raise(null, isComment ? + errors.unfinishedLongComment : + errors.unfinishedLongString, + firstLine, ''); } // ## Lex functions and helpers. @@ -982,7 +1318,7 @@ define(function(require, exports, module) { function expect(value) { if (value === token.value) next(); - else raise(token, errors.expected, value, token.value); + else raise(token, errors.expected, value, tokenValue(token)); } // ### Validation functions @@ -1004,14 +1340,23 @@ define(function(require, exports, module) { } // From [Lua 5.2](http://www.lua.org/manual/5.2/manual.html#8.1) onwards - // identifiers cannot use locale-dependet letters. + // identifiers cannot use 'locale-dependent' letters (i.e. dependent on the C locale). + // On the other hand, LuaJIT allows arbitrary octets ≥ 128 in identifiers. function isIdentifierStart(charCode) { - return (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || 95 === charCode; + if ((charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || 95 === charCode) + return true; + if (features.extendedIdentifiers && charCode >= 128) + return true; + return false; } function isIdentifierPart(charCode) { - return (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || 95 === charCode || (charCode >= 48 && charCode <= 57); + if ((charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || 95 === charCode || (charCode >= 48 && charCode <= 57)) + return true; + if (features.extendedIdentifiers && charCode >= 128) + return true; + return false; } // [3.1 Lexical Conventions](http://www.lua.org/manual/5.2/manual.html#3.1) @@ -1025,7 +1370,11 @@ define(function(require, exports, module) { case 3: return 'and' === id || 'end' === id || 'for' === id || 'not' === id; case 4: - return 'else' === id || 'goto' === id || 'then' === id; + if ('else' === id || 'then' === id) + return true; + if (features.labels && !features.contextualGoto) + return ('goto' === id); + return false; case 5: return 'break' === id || 'local' === id || 'until' === id || 'while' === id; case 6: @@ -1042,17 +1391,6 @@ define(function(require, exports, module) { return false; } - // @TODO this needs to be rethought. - function isCallExpression(expression) { - switch (expression.type) { - case 'CallExpression': - case 'TableCallExpression': - case 'StringCallExpression': - return true; - } - return false; - } - // Check if the token syntactically closes a block. function isBlockFollow(token) { @@ -1080,17 +1418,21 @@ define(function(require, exports, module) { // Create a new scope inheriting all declarations from the previous scope. function createScope() { - scopes.push(Array.apply(null, scopes[scopeDepth++])); + var scope = scopes[scopeDepth++].slice(); + scopes.push(scope); + if (options.onCreateScope) options.onCreateScope(); } // Exit and remove the current scope. - function exitScope() { - scopes.pop(); - scopeDepth--; + function destroyScope() { + var scope = scopes.pop(); + --scopeDepth; + if (options.onDestroyScope) options.onDestroyScope(); } // Add identifier name to the current scope if it doesnt already exist. function scopeIdentifierName(name) { + if (options.onLocalDeclaration) options.onLocalDeclaration(name); if (-1 !== indexOf(scopes[scopeDepth], name)) return; scopes[scopeDepth].push(name); } @@ -1149,14 +1491,36 @@ define(function(require, exports, module) { // of the *previous token* as an end location. Marker.prototype.complete = function() { if (options.locations) { - this.loc.end.line = previousToken.line; - this.loc.end.column = previousToken.range[1] - previousToken.lineStart; + this.loc.end.line = previousToken.lastLine || previousToken.line; + this.loc.end.column = previousToken.range[1] - (previousToken.lastLineStart || previousToken.lineStart); } if (options.ranges) { this.range[1] = previousToken.range[1]; } }; + Marker.prototype.bless = function (node) { + if (this.loc) { + var loc = this.loc; + node.loc = { + start: { + line: loc.start.line, + column: loc.start.column + }, + end: { + line: loc.end.line, + column: loc.end.column + } + }; + } + if (this.range) { + node.range = [ + this.range[0], + this.range[1] + ]; + } + }; + // Create a new `Marker` and add it to the FILO-array. function markLocation() { if (trackLocations) locations.push(createLocationMarker()); @@ -1167,6 +1531,156 @@ define(function(require, exports, module) { if (trackLocations) locations.push(marker); } + // Control flow tracking + // --------------------- + // A context object that validates loop breaks and `goto`-based control flow. + + function FullFlowContext() { + this.scopes = []; + this.pendingGotos = []; + } + + FullFlowContext.prototype.isInLoop = function () { + var i = this.scopes.length; + while (i --> 0) { + if (this.scopes[i].isLoop) + return true; + } + return false; + }; + + FullFlowContext.prototype.pushScope = function (isLoop) { + var scope = { + labels: {}, + locals: [], + deferredGotos: [], + isLoop: !!isLoop + }; + this.scopes.push(scope); + }; + + FullFlowContext.prototype.popScope = function () { + for (var i = 0; i < this.pendingGotos.length; ++i) { + var theGoto = this.pendingGotos[i]; + if (theGoto.maxDepth >= this.scopes.length) + if (--theGoto.maxDepth <= 0) + raise(theGoto.token, errors.labelNotVisible, theGoto.target); + } + + this.scopes.pop(); + }; + + FullFlowContext.prototype.addGoto = function (target, token) { + var localCounts = []; + + for (var i = 0; i < this.scopes.length; ++i) { + var scope = this.scopes[i]; + localCounts.push(scope.locals.length); + if (Object.prototype.hasOwnProperty.call(scope.labels, target)) + return; + } + + this.pendingGotos.push({ + maxDepth: this.scopes.length, + target: target, + token: token, + localCounts: localCounts + }); + }; + + FullFlowContext.prototype.addLabel = function (name, token) { + var scope = this.currentScope(); + + if (Object.prototype.hasOwnProperty.call(scope.labels, name)) { + raise(token, errors.labelAlreadyDefined, name, scope.labels[name].line); + } else { + var newGotos = []; + + for (var i = 0; i < this.pendingGotos.length; ++i) { + var theGoto = this.pendingGotos[i]; + + if (theGoto.maxDepth >= this.scopes.length && theGoto.target === name) { + if (theGoto.localCounts[this.scopes.length - 1] < scope.locals.length) { + scope.deferredGotos.push(theGoto); + } + continue; + } + + newGotos.push(theGoto); + } + + this.pendingGotos = newGotos; + } + + scope.labels[name] = { + localCount: scope.locals.length, + line: token.line + }; + }; + + FullFlowContext.prototype.addLocal = function (name, token) { + this.currentScope().locals.push({ + name: name, + token: token + }); + }; + + FullFlowContext.prototype.currentScope = function () { + return this.scopes[this.scopes.length - 1]; + }; + + FullFlowContext.prototype.raiseDeferredErrors = function () { + var scope = this.currentScope(); + var bads = scope.deferredGotos; + for (var i = 0; i < bads.length; ++i) { + var theGoto = bads[i]; + raise(theGoto.token, errors.gotoJumpInLocalScope, theGoto.target, scope.locals[theGoto.localCounts[this.scopes.length - 1]].name); + } + // Would be dead code currently, but may be useful later + // if (bads.length) + // scope.deferredGotos = []; + }; + + // Simplified context that only checks the validity of loop breaks. + + function LoopFlowContext() { + this.level = 0; + this.loopLevels = []; + } + + LoopFlowContext.prototype.isInLoop = function () { + return !!this.loopLevels.length; + }; + + LoopFlowContext.prototype.pushScope = function (isLoop) { + ++this.level; + if (isLoop) + this.loopLevels.push(this.level); + }; + + LoopFlowContext.prototype.popScope = function () { + var levels = this.loopLevels; + var levlen = levels.length; + if (levlen) { + if (levels[levlen - 1] === this.level) + levels.pop(); + } + --this.level; + }; + + LoopFlowContext.prototype.addGoto = + LoopFlowContext.prototype.addLabel = + /* istanbul ignore next */ + function () { throw new Error('This should never happen'); }; + + LoopFlowContext.prototype.addLocal = + LoopFlowContext.prototype.raiseDeferredErrors = + function () {}; + + function makeFlowContext() { + return features.labels ? new FullFlowContext() : new LoopFlowContext(); + } + // Parse functions // --------------- @@ -1177,7 +1691,13 @@ define(function(require, exports, module) { function parseChunk() { next(); markLocation(); - var body = parseBlock(); + if (options.scope) createScope(); + var flowContext = makeFlowContext(); + flowContext.allowVararg = true; + flowContext.pushScope(); + var body = parseBlock(flowContext); + flowContext.popScope(); + if (options.scope) destroyScope(); if (EOF !== token.type) unexpected(token); // If the body is empty no previousToken exists when finishNode runs. if (trackLocations && !body.length) previousToken = token; @@ -1189,26 +1709,24 @@ define(function(require, exports, module) { // // block ::= {stat} [retstat] - function parseBlock(terminator) { + function parseBlock(flowContext) { var block = [] , statement; - // Each block creates a new scope. - if (options.scope) createScope(); - while (!isBlockFollow(token)) { // Return has to be the last statement in a block. - if ('return' === token.value) { - block.push(parseStatement()); + // Likewise 'break' in Lua older than 5.2 + if ('return' === token.value || (!features.relaxedBreak && 'break' === token.value)) { + block.push(parseStatement(flowContext)); break; } - statement = parseStatement(); + statement = parseStatement(flowContext); + consume(';'); // Statements are only added if they are returned, this allows us to // ignore some statements, such as EmptyStatement. if (statement) block.push(statement); } - if (options.scope) exitScope(); // Doesn't really need an ast node return block; } @@ -1219,52 +1737,71 @@ define(function(require, exports, module) { // | if | for | function | local | label | assignment // | functioncall | ';' - function parseStatement() { + function parseStatement(flowContext) { markLocation(); + + if (Punctuator === token.type) { + if (consume('::')) return parseLabelStatement(flowContext); + } + + // When a `;` is encounted, simply eat it without storing it. + if (features.emptyStatement) { + if (consume(';')) { + if (trackLocations) locations.pop(); + return; + } + } + + flowContext.raiseDeferredErrors(); + if (Keyword === token.type) { switch (token.value) { - case 'local': next(); return parseLocalStatement(); - case 'if': next(); return parseIfStatement(); - case 'return': next(); return parseReturnStatement(); + case 'local': next(); return parseLocalStatement(flowContext); + case 'if': next(); return parseIfStatement(flowContext); + case 'return': next(); return parseReturnStatement(flowContext); case 'function': next(); var name = parseFunctionName(); return parseFunctionDeclaration(name); - case 'while': next(); return parseWhileStatement(); - case 'for': next(); return parseForStatement(); - case 'repeat': next(); return parseRepeatStatement(); - case 'break': next(); return parseBreakStatement(); - case 'do': next(); return parseDoStatement(); - case 'goto': next(); return parseGotoStatement(); + case 'while': next(); return parseWhileStatement(flowContext); + case 'for': next(); return parseForStatement(flowContext); + case 'repeat': next(); return parseRepeatStatement(flowContext); + case 'break': next(); + if (!flowContext.isInLoop()) + raise(token, errors.noLoopToBreak, token.value); + return parseBreakStatement(); + case 'do': next(); return parseDoStatement(flowContext); + case 'goto': next(); return parseGotoStatement(flowContext); } } - if (Punctuator === token.type) { - if (consume('::')) return parseLabelStatement(); + if (features.contextualGoto && + token.type === Identifier && token.value === 'goto' && + lookahead.type === Identifier && lookahead.value !== 'goto') { + next(); return parseGotoStatement(flowContext); } - // Assignments memorizes the location and pushes it manually for wrapper - // nodes. Additionally empty `;` statements should not mark a location. - if (trackLocations) locations.pop(); - // When a `;` is encounted, simply eat it without storing it. - if (consume(';')) return; + // Assignments memorizes the location and pushes it manually for wrapper nodes. + if (trackLocations) locations.pop(); - return parseAssignmentOrCallStatement(); + return parseAssignmentOrCallStatement(flowContext); } // ## Statements // label ::= '::' Name '::' - function parseLabelStatement() { - var name = token.value + function parseLabelStatement(flowContext) { + var nameToken = token , label = parseIdentifier(); if (options.scope) { - scopeIdentifierName('::' + name + '::'); + scopeIdentifierName('::' + nameToken.value + '::'); attachScope(label, true); } expect('::'); + + flowContext.addLabel(nameToken.value, nameToken); return finishNode(ast.labelStatement(label)); } @@ -1276,51 +1813,65 @@ define(function(require, exports, module) { // goto ::= 'goto' Name - function parseGotoStatement() { + function parseGotoStatement(flowContext) { var name = token.value + , gotoToken = previousToken , label = parseIdentifier(); - if (options.scope) label.isLabel = scopeHasName('::' + name + '::'); + flowContext.addGoto(name, gotoToken); return finishNode(ast.gotoStatement(label)); } // do ::= 'do' block 'end' - function parseDoStatement() { - var body = parseBlock(); + function parseDoStatement(flowContext) { + if (options.scope) createScope(); + flowContext.pushScope(); + var body = parseBlock(flowContext); + flowContext.popScope(); + if (options.scope) destroyScope(); expect('end'); return finishNode(ast.doStatement(body)); } // while ::= 'while' exp 'do' block 'end' - function parseWhileStatement() { - var condition = parseExpectedExpression(); + function parseWhileStatement(flowContext) { + var condition = parseExpectedExpression(flowContext); expect('do'); - var body = parseBlock(); + if (options.scope) createScope(); + flowContext.pushScope(true); + var body = parseBlock(flowContext); + flowContext.popScope(); + if (options.scope) destroyScope(); expect('end'); return finishNode(ast.whileStatement(condition, body)); } // repeat ::= 'repeat' block 'until' exp - function parseRepeatStatement() { - var body = parseBlock(); + function parseRepeatStatement(flowContext) { + if (options.scope) createScope(); + flowContext.pushScope(true); + var body = parseBlock(flowContext); expect('until'); - var condition = parseExpectedExpression(); + flowContext.raiseDeferredErrors(); + var condition = parseExpectedExpression(flowContext); + flowContext.popScope(); + if (options.scope) destroyScope(); return finishNode(ast.repeatStatement(condition, body)); } // retstat ::= 'return' [exp {',' exp}] [';'] - function parseReturnStatement() { + function parseReturnStatement(flowContext) { var expressions = []; if ('end' !== token.value) { - var expression = parseExpression(); + var expression = parseExpression(flowContext); if (null != expression) expressions.push(expression); while (consume(',')) { - expression = parseExpectedExpression(); + expression = parseExpectedExpression(flowContext); expressions.push(expression); } consume(';'); // grammar tells us ; is optional here. @@ -1331,7 +1882,7 @@ define(function(require, exports, module) { // if ::= 'if' exp 'then' block {elif} ['else' block] 'end' // elif ::= 'elseif' exp 'then' block - function parseIfStatement() { + function parseIfStatement(flowContext) { var clauses = [] , condition , body @@ -1343,17 +1894,25 @@ define(function(require, exports, module) { marker = locations[locations.length - 1]; locations.push(marker); } - condition = parseExpectedExpression(); + condition = parseExpectedExpression(flowContext); expect('then'); - body = parseBlock(); + if (options.scope) createScope(); + flowContext.pushScope(); + body = parseBlock(flowContext); + flowContext.popScope(); + if (options.scope) destroyScope(); clauses.push(finishNode(ast.ifClause(condition, body))); if (trackLocations) marker = createLocationMarker(); while (consume('elseif')) { pushLocation(marker); - condition = parseExpectedExpression(); + condition = parseExpectedExpression(flowContext); expect('then'); - body = parseBlock(); + if (options.scope) createScope(); + flowContext.pushScope(); + body = parseBlock(flowContext); + flowContext.popScope(); + if (options.scope) destroyScope(); clauses.push(finishNode(ast.elseifClause(condition, body))); if (trackLocations) marker = createLocationMarker(); } @@ -1364,7 +1923,11 @@ define(function(require, exports, module) { marker = new Marker(previousToken); locations.push(marker); } - body = parseBlock(); + if (options.scope) createScope(); + flowContext.pushScope(); + body = parseBlock(flowContext); + flowContext.popScope(); + if (options.scope) destroyScope(); clauses.push(finishNode(ast.elseClause(body))); } @@ -1379,27 +1942,34 @@ define(function(require, exports, module) { // namelist ::= Name {',' Name} // explist ::= exp {',' exp} - function parseForStatement() { + function parseForStatement(flowContext) { var variable = parseIdentifier() , body; // The start-identifier is local. - if (options.scope) scopeIdentifier(variable); + + if (options.scope) { + createScope(); + scopeIdentifier(variable); + } // If the first expression is followed by a `=` punctuator, this is a // Numeric For Statement. if (consume('=')) { // Start expression - var start = parseExpectedExpression(); + var start = parseExpectedExpression(flowContext); expect(','); // End expression - var end = parseExpectedExpression(); + var end = parseExpectedExpression(flowContext); // Optional step expression - var step = consume(',') ? parseExpectedExpression() : null; + var step = consume(',') ? parseExpectedExpression(flowContext) : null; expect('do'); - body = parseBlock(); + flowContext.pushScope(true); + body = parseBlock(flowContext); + flowContext.popScope(); expect('end'); + if (options.scope) destroyScope(); return finishNode(ast.forNumericStatement(variable, start, end, step, body)); } @@ -1418,13 +1988,16 @@ define(function(require, exports, module) { // One or more expressions in the explist. do { - var expression = parseExpectedExpression(); + var expression = parseExpectedExpression(flowContext); iterators.push(expression); } while (consume(',')); expect('do'); - body = parseBlock(); + flowContext.pushScope(true); + body = parseBlock(flowContext); + flowContext.popScope(); expect('end'); + if (options.scope) destroyScope(); return finishNode(ast.forGenericStatement(variables, iterators, body)); } @@ -1438,10 +2011,11 @@ define(function(require, exports, module) { // child. // // local ::= 'local' 'function' Name funcdecl - // | 'local' Name {',' Name} ['=' exp {',' exp} + // | 'local' Name {',' Name} ['=' exp {',' exp}] - function parseLocalStatement() { - var name; + function parseLocalStatement(flowContext) { + var name + , declToken = previousToken; if (Identifier === token.type) { var variables = [] @@ -1451,11 +2025,12 @@ define(function(require, exports, module) { name = parseIdentifier(); variables.push(name); + flowContext.addLocal(name.name, declToken); } while (consume(',')); if (consume('=')) { do { - var expression = parseExpectedExpression(); + var expression = parseExpectedExpression(flowContext); init.push(expression); } while (consume(',')); } @@ -1464,7 +2039,7 @@ define(function(require, exports, module) { // Therefore assignments can't use their declarator. And the identifiers // shouldn't be added to the scope until the statement is complete. if (options.scope) { - for (var i = 0, l = variables.length; i < l; i++) { + for (var i = 0, l = variables.length; i < l; ++i) { scopeIdentifier(variables[i]); } } @@ -1473,7 +2048,12 @@ define(function(require, exports, module) { } if (consume('function')) { name = parseIdentifier(); - if (options.scope) scopeIdentifier(name); + flowContext.addLocal(name.name, declToken); + + if (options.scope) { + scopeIdentifier(name); + createScope(); + } // MemberExpressions are not allowed in local function statements. return parseFunctionDeclaration(name, true); @@ -1483,52 +2063,93 @@ define(function(require, exports, module) { } // assignment ::= varlist '=' explist - // varlist ::= prefixexp {',' prefixexp} + // var ::= Name | prefixexp '[' exp ']' | prefixexp '.' Name + // varlist ::= var {',' var} // explist ::= exp {',' exp} // // call ::= callexp // callexp ::= prefixexp args | prefixexp ':' Name args - function parseAssignmentOrCallStatement() { + function parseAssignmentOrCallStatement(flowContext) { // Keep a reference to the previous token for better error messages in case // of invalid statement var previous = token - , expression, marker; + , marker, startMarker; + var lvalue, base, name; - if (trackLocations) marker = createLocationMarker(); - expression = parsePrefixExpression(); + var targets = []; - if (null == expression) return unexpected(token); - if (',='.indexOf(token.value) >= 0) { - var variables = [expression] - , init = [] - , exp; + if (trackLocations) startMarker = createLocationMarker(); - while (consume(',')) { - exp = parsePrefixExpression(); - if (null == exp) raiseUnexpectedToken('', token); - variables.push(exp); + do { + if (trackLocations) marker = createLocationMarker(); + + if (Identifier === token.type) { + name = token.value; + base = parseIdentifier(); + // Set the parent scope. + if (options.scope) attachScope(base, scopeHasName(name)); + lvalue = true; + } else if ('(' === token.value) { + next(); + base = parseExpectedExpression(flowContext); + expect(')'); + lvalue = false; + } else { + return unexpected(token); } - expect('='); - do { - exp = parseExpectedExpression(); - init.push(exp); - } while (consume(',')); + both: for (;;) { + var newBase; + + switch (StringLiteral === token.type ? '"' : token.value) { + case '.': + case '[': + lvalue = true; + break; + case ':': + case '(': + case '{': + case '"': + lvalue = null; + break; + default: + break both; + } + + base = parsePrefixExpressionPart(base, marker, flowContext); + } + + targets.push(base); + + if (',' !== token.value) + break; + + if (!lvalue) { + return unexpected(token); + } + + next(); + } while (true); + + if (targets.length === 1 && lvalue === null) { pushLocation(marker); - return finishNode(ast.assignmentStatement(variables, init)); - } - if (isCallExpression(expression)) { - pushLocation(marker); - return finishNode(ast.callStatement(expression)); + return finishNode(ast.callStatement(targets[0])); + } else if (!lvalue) { + return unexpected(token); } - // The prefix expression was neither part of an assignment or a - // callstatement, however as it was valid it's been consumed, so raise - // the exception on the previous token to provide a helpful message. - return unexpected(previous); - } + expect('='); + var values = []; + + do { + values.push(parseExpectedExpression(flowContext)); + } while (consume(',')); + + pushLocation(startMarker); + return finishNode(ast.assignmentStatement(targets, values)); + } // ### Non-statements @@ -1553,6 +2174,9 @@ define(function(require, exports, module) { // parlist ::= Name {',' Name} | [',' '...'] | '...' function parseFunctionDeclaration(name, isLocal) { + var flowContext = makeFlowContext(); + flowContext.pushScope(); + var parameters = []; expect('('); @@ -1569,21 +2193,23 @@ define(function(require, exports, module) { parameters.push(parameter); if (consume(',')) continue; - else if (consume(')')) break; } // No arguments are allowed after a vararg. else if (VarargLiteral === token.type) { - parameters.push(parsePrimaryExpression()); - expect(')'); - break; + flowContext.allowVararg = true; + parameters.push(parsePrimaryExpression(flowContext)); } else { raiseUnexpectedToken(' or \'...\'', token); } + expect(')'); + break; } } - var body = parseBlock(); + var body = parseBlock(flowContext); + flowContext.popScope(); expect('end'); + if (options.scope) destroyScope(); isLocal = isLocal || false; return finishNode(ast.functionStatement(name, parameters, isLocal, body)); @@ -1599,20 +2225,22 @@ define(function(require, exports, module) { if (trackLocations) marker = createLocationMarker(); base = parseIdentifier(); - if (options.scope) attachScope(base, false); + if (options.scope) { + attachScope(base, scopeHasName(base.name)); + createScope(); + } while (consume('.')) { pushLocation(marker); name = parseIdentifier(); - if (options.scope) attachScope(name, false); base = finishNode(ast.memberExpression(base, '.', name)); } if (consume(':')) { pushLocation(marker); name = parseIdentifier(); - if (options.scope) attachScope(name, false); base = finishNode(ast.memberExpression(base, ':', name)); + if (options.scope) scopeIdentifierName('self'); } return base; @@ -1624,28 +2252,30 @@ define(function(require, exports, module) { // // fieldsep ::= ',' | ';' - function parseTableConstructor() { + function parseTableConstructor(flowContext) { var fields = [] , key, value; while (true) { markLocation(); if (Punctuator === token.type && consume('[')) { - key = parseExpectedExpression(); + key = parseExpectedExpression(flowContext); expect(']'); expect('='); - value = parseExpectedExpression(); + value = parseExpectedExpression(flowContext); fields.push(finishNode(ast.tableKey(key, value))); } else if (Identifier === token.type) { - key = parseExpectedExpression(); - if (consume('=')) { - value = parseExpectedExpression(); + if ('=' === lookahead.value) { + key = parseIdentifier(); + next(); + value = parseExpectedExpression(flowContext); fields.push(finishNode(ast.tableKeyString(key, value))); } else { - fields.push(finishNode(ast.tableValue(key))); + value = parseExpectedExpression(flowContext); + fields.push(finishNode(ast.tableValue(value))); } } else { - if (null == (value = parseExpression())) { + if (null == (value = parseExpression(flowContext))) { locations.pop(); break; } @@ -1655,7 +2285,7 @@ define(function(require, exports, module) { next(); continue; } - if ('}' === token.value) break; + break; } expect('}'); return finishNode(ast.tableConstructorExpression(fields)); @@ -1676,15 +2306,15 @@ define(function(require, exports, module) { // | '.' Name | ':' Name args | args } // - function parseExpression() { - var expression = parseSubExpression(0); + function parseExpression(flowContext) { + var expression = parseSubExpression(0, flowContext); return expression; } // Parse an expression expecting it to be valid. - function parseExpectedExpression() { - var expression = parseExpression(); + function parseExpectedExpression(flowContext) { + var expression = parseExpression(flowContext); if (null == expression) raiseUnexpectedToken('', token); else return expression; } @@ -1704,16 +2334,22 @@ define(function(require, exports, module) { if (1 === length) { switch (charCode) { - case 94: return 10; // ^ - case 42: case 47: case 37: return 7; // * / % - case 43: case 45: return 6; // + - + case 94: return 12; // ^ + case 42: case 47: case 37: return 10; // * / % + case 43: case 45: return 9; // + - + case 38: return 6; // & + case 126: return 5; // ~ + case 124: return 4; // | case 60: case 62: return 3; // < > - case 38: case 124: return 7; // & | } } else if (2 === length) { switch (charCode) { - case 46: return 5; // .. - case 60: case 62: case 61: case 126: return 3; // <= >= == ~= + case 47: return 10; // // + case 46: return 8; // .. + case 60: case 62: + if('<<' === operator || '>>' === operator) return 7; // << >> + return 3; // <= >= + case 61: case 126: return 3; // == ~= case 111: return 1; // or } } else if (97 === charCode && 'and' === operator) return 2; @@ -1729,7 +2365,7 @@ define(function(require, exports, module) { // // exp ::= (unop exp | primary | prefixexp ) { binop exp } - function parseSubExpression(minPrecedence) { + function parseSubExpression(minPrecedence, flowContext) { var operator = token.value // The left-hand side in binary operations. , expression, marker; @@ -1740,17 +2376,17 @@ define(function(require, exports, module) { if (isUnary(token)) { markLocation(); next(); - var argument = parseSubExpression(8); + var argument = parseSubExpression(10, flowContext); if (argument == null) raiseUnexpectedToken('', token); expression = finishNode(ast.unaryExpression(operator, argument)); } if (null == expression) { // PrimaryExpression - expression = parsePrimaryExpression(); + expression = parsePrimaryExpression(flowContext); // PrefixExpression if (null == expression) { - expression = parsePrefixExpression(); + expression = parsePrefixExpression(flowContext); } } // This is not a valid left hand expression. @@ -1765,9 +2401,9 @@ define(function(require, exports, module) { if (precedence === 0 || precedence <= minPrecedence) break; // Right-hand precedence operators - if ('^' === operator || '..' === operator) precedence--; + if ('^' === operator || '..' === operator) --precedence; next(); - var right = parseSubExpression(precedence); + var right = parseSubExpression(precedence, flowContext); if (null == right) raiseUnexpectedToken('', token); // Push in the marker created before the loop to wrap its entirety. if (trackLocations) locations.push(marker); @@ -1783,10 +2419,45 @@ define(function(require, exports, module) { // // args ::= '(' [explist] ')' | tableconstructor | String - function parsePrefixExpression() { - var base, name, marker - // Keep track of the scope, if a parent is local so are the children. - , isLocal; + function parsePrefixExpressionPart(base, marker, flowContext) { + var expression, identifier; + + if (Punctuator === token.type) { + switch (token.value) { + case '[': + pushLocation(marker); + next(); + expression = parseExpectedExpression(flowContext); + expect(']'); + return finishNode(ast.indexExpression(base, expression)); + case '.': + pushLocation(marker); + next(); + identifier = parseIdentifier(); + return finishNode(ast.memberExpression(base, '.', identifier)); + case ':': + pushLocation(marker); + next(); + identifier = parseIdentifier(); + base = finishNode(ast.memberExpression(base, ':', identifier)); + // Once a : is found, this has to be a CallExpression, otherwise + // throw an error. + pushLocation(marker); + return parseCallExpression(base, flowContext); + case '(': case '{': // args + pushLocation(marker); + return parseCallExpression(base, flowContext); + } + } else if (StringLiteral === token.type) { + pushLocation(marker); + return parseCallExpression(base, flowContext); + } + + return null; + } + + function parsePrefixExpression(flowContext) { + var base, name, marker; if (trackLocations) marker = createLocationMarker(); @@ -1795,59 +2466,20 @@ define(function(require, exports, module) { name = token.value; base = parseIdentifier(); // Set the parent scope. - if (options.scope) attachScope(base, isLocal = scopeHasName(name)); + if (options.scope) attachScope(base, scopeHasName(name)); } else if (consume('(')) { - base = parseExpectedExpression(); + base = parseExpectedExpression(flowContext); expect(')'); - if (options.scope) isLocal = base.isLocal; } else { return null; } // The suffix - var expression, identifier; - while (true) { - if (Punctuator === token.type) { - switch (token.value) { - case '[': - pushLocation(marker); - next(); - expression = parseExpectedExpression(); - base = finishNode(ast.indexExpression(base, expression)); - expect(']'); - break; - case '.': - pushLocation(marker); - next(); - identifier = parseIdentifier(); - // Inherit the scope - if (options.scope) attachScope(identifier, isLocal); - base = finishNode(ast.memberExpression(base, '.', identifier)); - break; - case ':': - pushLocation(marker); - next(); - identifier = parseIdentifier(); - if (options.scope) attachScope(identifier, isLocal); - base = finishNode(ast.memberExpression(base, ':', identifier)); - // Once a : is found, this has to be a CallExpression, otherwise - // throw an error. - pushLocation(marker); - base = parseCallExpression(base); - break; - case '(': case '{': // args - pushLocation(marker); - base = parseCallExpression(base); - break; - default: - return base; - } - } else if (StringLiteral === token.type) { - pushLocation(marker); - base = parseCallExpression(base); - } else { + for (;;) { + var newBase = parsePrefixExpressionPart(base, marker, flowContext); + if (newBase === null) break; - } + base = newBase; } return base; @@ -1855,18 +2487,22 @@ define(function(require, exports, module) { // args ::= '(' [explist] ')' | tableconstructor | String - function parseCallExpression(base) { + function parseCallExpression(base, flowContext) { if (Punctuator === token.type) { switch (token.value) { case '(': + if (!features.emptyStatement) { + if (token.line !== previousToken.line) + raise(null, errors.ambiguousSyntax, token.value); + } next(); // List of expressions var expressions = []; - var expression = parseExpression(); + var expression = parseExpression(flowContext); if (null != expression) expressions.push(expression); while (consume(',')) { - expression = parseExpectedExpression(); + expression = parseExpectedExpression(flowContext); expressions.push(expression); } @@ -1876,11 +2512,11 @@ define(function(require, exports, module) { case '{': markLocation(); next(); - var table = parseTableConstructor(); + var table = parseTableConstructor(flowContext); return finishNode(ast.tableCallExpression(base, table)); } } else if (StringLiteral === token.type) { - return finishNode(ast.stringCallExpression(base, parsePrimaryExpression())); + return finishNode(ast.stringCallExpression(base, parsePrimaryExpression(flowContext))); } raiseUnexpectedToken('function arguments', token); @@ -1889,7 +2525,7 @@ define(function(require, exports, module) { // primary ::= String | Numeric | nil | true | false // | functiondef | tableconstructor | '...' - function parsePrimaryExpression() { + function parsePrimaryExpression(flowContext) { var literals = StringLiteral | NumericLiteral | BooleanLiteral | NilLiteral | VarargLiteral , value = token.value , type = token.type @@ -1897,6 +2533,10 @@ define(function(require, exports, module) { if (trackLocations) marker = createLocationMarker(); + if (type === VarargLiteral && !flowContext.allowVararg) { + raise(token, errors.cannotUseVararg, token.value); + } + if (type & literals) { pushLocation(marker); var raw = input.slice(token.range[0], token.range[1]); @@ -1905,10 +2545,11 @@ define(function(require, exports, module) { } else if (Keyword === type && 'function' === value) { pushLocation(marker); next(); + if (options.scope) createScope(); return parseFunctionDeclaration(null); } else if (consume('{')) { pushLocation(marker); - return parseTableConstructor(); + return parseTableConstructor(flowContext); } } @@ -1920,6 +2561,15 @@ define(function(require, exports, module) { // - `wait` Hold parsing until end() is called. Defaults to false // - `comments` Store comments. Defaults to true. // - `scope` Track identifier scope. Defaults to false. + // - `locations` Store location information. Defaults to false. + // - `ranges` Store the start and end character locations. Defaults to + // false. + // - `onCreateNode` Callback which will be invoked when a syntax node is + // created. + // - `onCreateScope` Callback which will be invoked when a new scope is + // created. + // - `onDestroyScope` Callback which will be invoked when the current scope + // is destroyed. // // Example: // @@ -1928,6 +2578,43 @@ define(function(require, exports, module) { exports.parse = parse; + var versionFeatures = { + '5.1': { + }, + '5.2': { + labels: true, + emptyStatement: true, + hexEscapes: true, + skipWhitespaceEscape: true, + strictEscapes: true, + relaxedBreak: true + }, + '5.3': { + labels: true, + emptyStatement: true, + hexEscapes: true, + skipWhitespaceEscape: true, + strictEscapes: true, + unicodeEscapes: true, + bitwiseOperators: true, + integerDivision: true, + relaxedBreak: true + }, + 'LuaJIT': { + // XXX: LuaJIT language features may depend on compilation options; may need to + // rethink how to handle this. Specifically, there is a LUAJIT_ENABLE_LUA52COMPAT + // that removes contextual goto. Maybe add 'LuaJIT-5.2compat' as well? + labels: true, + contextualGoto: true, + hexEscapes: true, + skipWhitespaceEscape: true, + strictEscapes: true, + unicodeEscapes: true, + imaginaryNumbers: true, + integerSuffixes: true + } + }; + function parse(_input, _options) { if ('undefined' === typeof _options && 'object' === typeof _input) { _options = _input; @@ -1936,7 +2623,7 @@ define(function(require, exports, module) { if (!_options) _options = {}; input = _input || ''; - options = extend(defaultOptions, _options); + options = assign({}, defaultOptions, _options); // Rewind the lexer index = 0; @@ -1949,6 +2636,20 @@ define(function(require, exports, module) { globals = []; locations = []; + if (!Object.prototype.hasOwnProperty.call(versionFeatures, options.luaVersion)) { + throw new Error(sprintf("Lua version '%1' not supported", options.luaVersion)); + } + + features = assign({}, versionFeatures[options.luaVersion]); + if (options.extendedIdentifiers !== void 0) + features.extendedIdentifiers = !!options.extendedIdentifiers; + + if (!Object.prototype.hasOwnProperty.call(encodingModes, options.encodingMode)) { + throw new Error(sprintf("Encoding mode '%1' not supported", options.encodingMode)); + } + + encodingMode = encodingModes[options.encodingMode]; + if (options.comments) comments = []; if (!options.wait) return end(); return exports; @@ -1969,6 +2670,11 @@ define(function(require, exports, module) { function end(_input) { if ('undefined' !== typeof _input) write(_input); + // Ignore shebangs. + if (input && input.substr(0, 2) === '#!') input = input.replace(/^.*/, function (line) { + return line.replace(/./g, ' '); + }); + length = input.length; trackLocations = options.locations || options.ranges; // Initialize with a lookahead token. @@ -1978,6 +2684,7 @@ define(function(require, exports, module) { if (options.comments) chunk.comments = comments; if (options.scope) chunk.globals = globals; + /* istanbul ignore if */ if (locations.length > 0) throw new Error('Location tracking failed. This is most likely a bug in luaparse'); @@ -1987,4 +2694,4 @@ define(function(require, exports, module) { })); /* vim: set sw=2 ts=2 et tw=79 : */ -}); +}); \ No newline at end of file diff --git a/lib/ace/mode/lua_worker.js b/lib/ace/mode/lua_worker.js index dcff9514569..9d9486a42d2 100644 --- a/lib/ace/mode/lua_worker.js +++ b/lib/ace/mode/lua_worker.js @@ -52,7 +52,7 @@ oop.inherits(Worker, Mirror); try { luaparse.parse(value); } catch(e) { - if (e instanceof SyntaxError) { + if (e instanceof luaparse.SyntaxError) { errors.push({ row: e.line - 1, column: e.column, diff --git a/lib/ace/mode/luapage.js b/lib/ace/mode/luapage.js deleted file mode 100644 index 5ea79d14fab..00000000000 --- a/lib/ace/mode/luapage.js +++ /dev/null @@ -1,24 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var HtmlMode = require("./html").Mode; -var LuaMode = require("./lua").Mode; -var LuaPageHighlightRules = require("./luapage_highlight_rules").LuaPageHighlightRules; - -var Mode = function() { - HtmlMode.call(this); - - this.HighlightRules = LuaPageHighlightRules; - this.createModeDelegates({ - "lua-": LuaMode - }); -}; -oop.inherits(Mode, HtmlMode); - -(function() { - this.$id = "ace/mode/luapage"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/lucene.js b/lib/ace/mode/lucene.js deleted file mode 100644 index 36983e92394..00000000000 --- a/lib/ace/mode/lucene.js +++ /dev/null @@ -1,20 +0,0 @@ -define(function(require, exports, module) { -'use strict'; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var LuceneHighlightRules = require("./lucene_highlight_rules").LuceneHighlightRules; - -var Mode = function() { - this.HighlightRules = LuceneHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; - -oop.inherits(Mode, TextMode); - -(function() { - this.$id = "ace/mode/lucene"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/lucene_highlight_rules.js b/lib/ace/mode/lucene_highlight_rules.js deleted file mode 100644 index 536aa1d30f0..00000000000 --- a/lib/ace/mode/lucene_highlight_rules.js +++ /dev/null @@ -1,49 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var LuceneHighlightRules = function() { - this.$rules = { - "start" : [ - { - token : "constant.character.negation", - regex : "[\\-]" - }, { - token : "constant.character.interro", - regex : "[\\?]" - }, { - token : "constant.character.asterisk", - regex : "[\\*]" - }, { - token: 'constant.character.proximity', - regex: '~[0-9]+\\b' - }, { - token : 'keyword.operator', - regex: '(?:AND|OR|NOT)\\b' - }, { - token : "paren.lparen", - regex : "[\\(]" - }, { - token : "paren.rparen", - regex : "[\\)]" - }, { - token : "keyword", - regex : "[\\S]+:" - }, { - token : "string", // " string - regex : '".*?"' - }, { - token : "text", - regex : "\\s+" - } - ] - }; -}; - -oop.inherits(LuceneHighlightRules, TextHighlightRules); - -exports.LuceneHighlightRules = LuceneHighlightRules; -}); diff --git a/lib/ace/mode/makefile.js b/lib/ace/mode/makefile.js deleted file mode 100644 index df599327993..00000000000 --- a/lib/ace/mode/makefile.js +++ /dev/null @@ -1,59 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var MakefileHighlightRules = require("./makefile_highlight_rules").MakefileHighlightRules; -var FoldMode = require("./folding/coffee").FoldMode; - -var Mode = function() { - this.HighlightRules = MakefileHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "#"; - this.$indentWithTabs = true; - - this.$id = "ace/mode/makefile"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/markdown.js b/lib/ace/mode/markdown.js deleted file mode 100644 index 61a96f7edd0..00000000000 --- a/lib/ace/mode/markdown.js +++ /dev/null @@ -1,80 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var JavaScriptMode = require("./javascript").Mode; -var XmlMode = require("./xml").Mode; -var HtmlMode = require("./html").Mode; -var MarkdownHighlightRules = require("./markdown_highlight_rules").MarkdownHighlightRules; -var MarkdownFoldMode = require("./folding/markdown").FoldMode; - -var Mode = function() { - this.HighlightRules = MarkdownHighlightRules; - - this.createModeDelegates({ - javascript: require("./javascript").Mode, - html: require("./html").Mode, - bash: require("./sh").Mode, - sh: require("./sh").Mode, - xml: require("./xml").Mode, - css: require("./css").Mode - }); - - this.foldingRules = new MarkdownFoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.type = "text"; - this.blockComment = {start: ""}; - - this.getNextLineIndent = function(state, line, tab) { - if (state == "listblock") { - var match = /^(\s*)(?:([-+*])|(\d+)\.)(\s+)/.exec(line); - if (!match) - return ""; - var marker = match[2]; - if (!marker) - marker = parseInt(match[3], 10) + 1 + "."; - return match[1] + marker + match[4]; - } else { - return this.$getIndent(line); - } - }; - this.$id = "ace/mode/markdown"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/mask.js b/lib/ace/mode/mask.js deleted file mode 100644 index ee94c82f18c..00000000000 --- a/lib/ace/mode/mask.js +++ /dev/null @@ -1,84 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2014, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var MaskHighlightRules = require("./mask_highlight_rules").MaskHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CssBehaviour = require("./behaviour/css").CssBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = MaskHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CssBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - // ignore braces in comments - var tokens = this.getTokenizer().getLineTokens(line, state).tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - var match = line.match(/^.*\{\s*$/); - if (match) { - indent += tab; - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/mask"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); diff --git a/lib/ace/mode/matching_brace_outdent.js b/lib/ace/mode/matching_brace_outdent.js deleted file mode 100644 index 07f4829e60c..00000000000 --- a/lib/ace/mode/matching_brace_outdent.js +++ /dev/null @@ -1,69 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var Range = require("../range").Range; - -var MatchingBraceOutdent = function() {}; - -(function() { - - this.checkOutdent = function(line, input) { - if (! /^\s+$/.test(line)) - return false; - - return /^\s*\}/.test(input); - }; - - this.autoOutdent = function(doc, row) { - var line = doc.getLine(row); - var match = line.match(/^(\s*\})/); - - if (!match) return 0; - - var column = match[1].length; - var openBracePos = doc.findMatchingBracket({row: row, column: column}); - - if (!openBracePos || openBracePos.row == row) return 0; - - var indent = this.$getIndent(doc.getLine(openBracePos.row)); - doc.replace(new Range(row, 0, row, column-1), indent); - }; - - this.$getIndent = function(line) { - return line.match(/^\s*/)[0]; - }; - -}).call(MatchingBraceOutdent.prototype); - -exports.MatchingBraceOutdent = MatchingBraceOutdent; -}); diff --git a/lib/ace/mode/matching_parens_outdent.js b/lib/ace/mode/matching_parens_outdent.js deleted file mode 100644 index 0aadf6e8c28..00000000000 --- a/lib/ace/mode/matching_parens_outdent.js +++ /dev/null @@ -1,74 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var Range = require("../range").Range; - -var MatchingParensOutdent = function() {}; - -(function() { - - this.checkOutdent = function(line, input) { - if (! /^\s+$/.test(line)) - return false; - - return /^\s*\)/.test(input); - }; - - this.autoOutdent = function(doc, row) { - var line = doc.getLine(row); - var match = line.match(/^(\s*\))/); - - if (!match) return 0; - - var column = match[1].length; - var openBracePos = doc.findMatchingBracket({row: row, column: column}); - - if (!openBracePos || openBracePos.row == row) return 0; - - var indent = this.$getIndent(doc.getLine(openBracePos.row)); - doc.replace(new Range(row, 0, row, column-1), indent); - }; - - this.$getIndent = function(line) { - var match = line.match(/^(\s+)/); - if (match) { - return match[1]; - } - - return ""; - }; - -}).call(MatchingParensOutdent.prototype); - -exports.MatchingParensOutdent = MatchingParensOutdent; -}); diff --git a/lib/ace/mode/matlab.js b/lib/ace/mode/matlab.js deleted file mode 100644 index 91f6bb634a2..00000000000 --- a/lib/ace/mode/matlab.js +++ /dev/null @@ -1,55 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var MatlabHighlightRules = require("./matlab_highlight_rules").MatlabHighlightRules; - -var Mode = function() { - this.HighlightRules = MatlabHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "%"; - this.blockComment = {start: "%{", end: "%}"}; - - this.$id = "ace/mode/matlab"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); - diff --git a/lib/ace/mode/maze.js b/lib/ace/mode/maze.js deleted file mode 100644 index a23631f89be..00000000000 --- a/lib/ace/mode/maze.js +++ /dev/null @@ -1,53 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var MazeHighlightRules = require("./maze_highlight_rules").MazeHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = MazeHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.$id = "ace/mode/maze"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/maze_highlight_rules.js b/lib/ace/mode/maze_highlight_rules.js deleted file mode 100644 index 04bed89c32b..00000000000 --- a/lib/ace/mode/maze_highlight_rules.js +++ /dev/null @@ -1,154 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var MazeHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { - start: [{ - token: "keyword.control", - regex: /##|``/, - comment: "Wall" - }, { - token: "entity.name.tag", - regex: /\.\./, - comment: "Path" - }, { - token: "keyword.control", - regex: /<>/, - comment: "Splitter" - }, { - token: "entity.name.tag", - regex: /\*[\*A-Za-z0-9]/, - comment: "Signal" - }, { - token: "constant.numeric", - regex: /[0-9]{2}/, - comment: "Pause" - }, { - token: "keyword.control", - regex: /\^\^/, - comment: "Start" - }, { - token: "keyword.control", - regex: /\(\)/, - comment: "Hole" - }, { - token: "support.function", - regex: />>/, - comment: "Out" - }, { - token: "support.function", - regex: />\//, - comment: "Ln Out" - }, { - token: "support.function", - regex: /< *)(?:([-+*\/]=)( *)((?:-)?)([0-9]+)|(=)( *)(?:((?:-)?)([0-9]+)|("[^"]*")|('[^']*')))/, - comment: "Assignment function" - }, { - token: [ - "entity.name.function", - "keyword.other", - "keyword.control", - "keyword.other", - "keyword.operator", - "keyword.other", - "keyword.operator", - "constant.numeric", - "entity.name.tag", - "keyword.other", - "keyword.control", - "keyword.other", - "constant.language", - "keyword.other", - "keyword.control", - "keyword.other", - "constant.language" - ], - regex: /([A-Za-z][A-Za-z0-9])( *-> *)(IF|if)( *)(?:([<>]=?|==)( *)((?:-)?)([0-9]+)|(\*[\*A-Za-z0-9]))( *)(THEN|then)( *)(%[LRUDNlrudn])(?:( *)(ELSE|else)( *)(%[LRUDNlrudn]))?/, - comment: "Equality Function" - }, { - token: "entity.name.function", - regex: /[A-Za-z][A-Za-z0-9]/, - comment: "Function cell" - }, { - token: "comment.line.double-slash", - regex: / *\/\/.*/, - comment: "Comment" - }] - }; - - this.normalizeRules(); -}; - -MazeHighlightRules.metaData = { - fileTypes: ["mz"], - name: "Maze", - scopeName: "source.maze" -}; - - -oop.inherits(MazeHighlightRules, TextHighlightRules); - -exports.MazeHighlightRules = MazeHighlightRules; -}); diff --git a/lib/ace/mode/mel.js b/lib/ace/mode/mel.js deleted file mode 100644 index e8922a1cb59..00000000000 --- a/lib/ace/mode/mel.js +++ /dev/null @@ -1,56 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var MELHighlightRules = require("./mel_highlight_rules").MELHighlightRules; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = MELHighlightRules; - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - this.$id = "ace/mode/mel"; -}).call(Mode.prototype); - -exports.Mode = Mode; - -}); \ No newline at end of file diff --git a/lib/ace/mode/mixal.js b/lib/ace/mode/mixal.js deleted file mode 100644 index af45bc71590..00000000000 --- a/lib/ace/mode/mixal.js +++ /dev/null @@ -1,49 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2017, Ruslan Batdalov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var MixalHighlightRules = require("./mixal_highlight_rules").MixalHighlightRules; - -var Mode = function() { - this.HighlightRules = MixalHighlightRules; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.$id = "ace/mode/mixal"; - this.lineCommentStart = "*"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/mixal_highlight_rules.js b/lib/ace/mode/mixal_highlight_rules.js deleted file mode 100644 index 5a0482a64df..00000000000 --- a/lib/ace/mode/mixal_highlight_rules.js +++ /dev/null @@ -1,125 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2017, Ruslan Batdalov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var MixalHighlightRules = function() { - var isValidSymbol = function(string) { - return string && string.search(/^[A-Z\u0394\u03a0\u03a30-9]{1,10}$/) > -1 && string.search(/[A-Z\u0394\u03a0\u03a3]/) > -1; - }; - - var isValidOp = function(op) { - return op && [ - 'NOP', 'ADD', 'FADD', 'SUB', 'FSUB', 'MUL', 'FMUL', 'DIV', 'FDIV', 'NUM', 'CHAR', 'HLT', - 'SLA', 'SRA', 'SLAX', 'SRAX', 'SLC', 'SRC', 'MOVE', 'LDA', 'LD1', 'LD2', 'LD3', 'LD4', - 'LD5', 'LD6', 'LDX', 'LDAN', 'LD1N', 'LD2N', 'LD3N', 'LD4N', 'LD5N', 'LD6N', 'LDXN', - 'STA', 'ST1', 'ST2', 'ST3', 'ST4', 'ST5', 'ST6', 'STX', 'STJ', 'STZ', 'JBUS', 'IOC', - 'IN', 'OUT', 'JRED', 'JMP', 'JSJ', 'JOV', 'JNOV', 'JL', 'JE', 'JG', 'JGE', 'JNE', 'JLE', - 'JAN', 'JAZ', 'JAP', 'JANN', 'JANZ', 'JANP', 'J1N', 'J1Z', 'J1P', 'J1NN', 'J1NZ', - 'J1NP', 'J2N', 'J2Z', 'J2P', 'J2NN', 'J2NZ', 'J2NP','J3N', 'J3Z', 'J3P', 'J3NN', 'J3NZ', - 'J3NP', 'J4N', 'J4Z', 'J4P', 'J4NN', 'J4NZ', 'J4NP', 'J5N', 'J5Z', 'J5P', 'J5NN', - 'J5NZ', 'J5NP','J6N', 'J6Z', 'J6P', 'J6NN', 'J6NZ', 'J6NP', 'JXAN', 'JXZ', 'JXP', - 'JXNN', 'JXNZ', 'JXNP', 'INCA', 'DECA', 'ENTA', 'ENNA', 'INC1', 'DEC1', 'ENT1', 'ENN1', - 'INC2', 'DEC2', 'ENT2', 'ENN2', 'INC3', 'DEC3', 'ENT3', 'ENN3', 'INC4', 'DEC4', 'ENT4', - 'ENN4', 'INC5', 'DEC5', 'ENT5', 'ENN5', 'INC6', 'DEC6', 'ENT6', 'ENN6', 'INCX', 'DECX', - 'ENTX', 'ENNX', 'CMPA', 'FCMP', 'CMP1', 'CMP2', 'CMP3', 'CMP4', 'CMP5', 'CMP6', 'CMPX', - 'EQU', 'ORIG', 'CON', 'ALF', 'END' - ].indexOf(op) > -1; - }; - - var containsOnlySupportedCharacters = function(string) { - return string && string.search(/[^ A-Z\u0394\u03a0\u03a30-9.,()+*/=$<>@;:'-]/) == -1; - }; - - this.$rules = { - "start" : [{ - token: "comment.line.character", - regex: /^ *\*.*$/ - }, { - token: function(label, space0, keyword, space1, literal, comment) { - return [ - isValidSymbol(label) ? "variable.other" : "invalid.illegal", - "text", - "keyword.control", - "text", - containsOnlySupportedCharacters(literal) ? "text" : "invalid.illegal", - "comment.line.character" - ]; - }, - regex: /^(\S+)?( +)(ALF)( )(.{5})(\s+.*)?$/ - }, { - token: function(label, space0, keyword, space1, literal, comment) { - return [ - isValidSymbol(label) ? "variable.other" : "invalid.illegal", - "text", - "keyword.control", - "text", - containsOnlySupportedCharacters(literal) ? "text" : "invalid.illegal", - "comment.line.character" - ]; - }, - regex: /^(\S+)?( +)(ALF)( )(\S.{4})(\s+.*)?$/ - }, { - token: function(label, space0, op, comment) { - return [ - isValidSymbol(label) ? "variable.other" : "invalid.illegal", - "text", - isValidOp(op) ? "keyword.control" : "invalid.illegal", - "comment.line.character" - ]; - }, - regex: /^(\S+)?( +)(\S+)(?:\s*)$/ - }, { - token: function(label, space0, op, space1, address, comment) { - return [ - isValidSymbol(label) ? "variable.other" : "invalid.illegal", - "text", - isValidOp(op) ? "keyword.control" : "invalid.illegal", - "text", - containsOnlySupportedCharacters(address) ? "text" : "invalid.illegal", - "comment.line.character" - ]; - }, - regex: /^(\S+)?( +)(\S+)( +)(\S+)(\s+.*)?$/ - }, { - defaultToken: "text" - }] - }; -}; - -oop.inherits(MixalHighlightRules, TextHighlightRules); - -exports.MixalHighlightRules = MixalHighlightRules; - -}); diff --git a/lib/ace/mode/mushcode.js b/lib/ace/mode/mushcode.js deleted file mode 100644 index b36ad23a5a7..00000000000 --- a/lib/ace/mode/mushcode.js +++ /dev/null @@ -1,116 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var MushCodeRules = require("./mushcode_highlight_rules").MushCodeRules; -var PythonFoldMode = require("./folding/pythonic").FoldMode; -var Range = require("../range").Range; - -var Mode = function() { - this.HighlightRules = MushCodeRules; - this.foldingRules = new PythonFoldMode("\\:"); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[:]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - var outdents = { - "pass": 1, - "return": 1, - "raise": 1, - "break": 1, - "continue": 1 - }; - - this.checkOutdent = function(state, line, input) { - if (input !== "\r\n" && input !== "\r" && input !== "\n") - return false; - - var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens; - - if (!tokens) - return false; - - // ignore trailing comments - do { - var last = tokens.pop(); - } while (last && (last.type == "comment" || (last.type == "text" && last.value.match(/^\s+$/)))); - - if (!last) - return false; - - return (last.type == "keyword" && outdents[last.value]); - }; - - this.autoOutdent = function(state, doc, row) { - // outdenting in python is slightly different because it always applies - // to the next line and only of a new line is inserted - - row += 1; - var indent = this.$getIndent(doc.getLine(row)); - var tab = doc.getTabString(); - if (indent.slice(-tab.length) == tab) - doc.remove(new Range(row, indent.length-tab.length, row, indent.length)); - }; - - this.$id = "ace/mode/mushcode"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); - - - diff --git a/lib/ace/mode/mysql.js b/lib/ace/mode/mysql.js deleted file mode 100644 index 64b06eb7450..00000000000 --- a/lib/ace/mode/mysql.js +++ /dev/null @@ -1,51 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var oop = require("../lib/oop"); -var TextMode = require("../mode/text").Mode; -var MysqlHighlightRules = require("./mysql_highlight_rules").MysqlHighlightRules; - -var Mode = function() { - this.HighlightRules = MysqlHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = ["--", "#"]; // todo space - this.blockComment = {start: "/*", end: "*/"}; - - this.$id = "ace/mode/mysql"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/mysql_highlight_rules.js b/lib/ace/mode/mysql_highlight_rules.js deleted file mode 100644 index aefb72c4745..00000000000 --- a/lib/ace/mode/mysql_highlight_rules.js +++ /dev/null @@ -1,122 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var MysqlHighlightRules = function() { - - var mySqlKeywords = /*sql*/ "alter|and|as|asc|between|count|create|delete|desc|distinct|drop|from|having|in|insert|into|is|join|like|not|on|or|order|select|set|table|union|update|values|where" - /*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|coalesce|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|groupby_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"; - var builtins = "by|bool|boolean|bit|blob|decimal|double|enum|float|long|longblob|longtext|medium|mediumblob|mediumint|mediumtext|time|timestamp|tinyblob|tinyint|tinytext|text|bigint|int|int1|int2|int3|int4|int8|integer|float|float4|float8|double|char|varbinary|varchar|varcharacter|precision|date|datetime|year|unsigned|signed|numeric|ucase|lcase|mid|len|round|rank|now|format|coalesce|ifnull|isnull|nvl"; - var variable = "charset|clear|connect|edit|ego|exit|go|help|nopager|notee|nowarning|pager|print|prompt|quit|rehash|source|status|system|tee"; - - //operatorChars: /^[*+\-%<>!=&|^]/, - - var keywordMapper = this.createKeywordMapper({ - "support.function": builtins, - "keyword": mySqlKeywords, - "constant": "false|true|null|unknown|date|time|timestamp|ODBCdotTable|zerolessFloat", - "variable.language": variable - }, "identifier", true); - - - function string(rule) { - var start = rule.start; - var escapeSeq = rule.escape; - return { - token: "string.start", - regex: start, - next: [ - {token: "constant.language.escape", regex: escapeSeq}, - {token: "string.end", next: "start", regex: start}, - {defaultToken: "string"} - ] - }; - } - - this.$rules = { - "start" : [ { - token : "comment", regex : "(?:-- |#).*$" - }, - string({start: '"', escape: /\\[0'"bnrtZ\\%_]?/}), - string({start: "'", escape: /\\[0'"bnrtZ\\%_]?/}), - DocCommentHighlightRules.getStartRule("doc-start"), - { - token : "comment", // multi line comment - regex : /\/\*/, - next : "comment" - }, { - token : "constant.numeric", // hex - regex : /0[xX][0-9a-fA-F]+|[xX]'[0-9a-fA-F]+'|0[bB][01]+|[bB]'[01]+'/ - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "constant.class", - regex : "@@?[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "constant.buildin", - regex : "`[^`]*`" - }, { - token : "keyword.operator", - regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|=" - }, { - token : "paren.lparen", - regex : "[\\(]" - }, { - token : "paren.rparen", - regex : "[\\)]" - }, { - token : "text", - regex : "\\s+" - } ], - "comment" : [ - {token : "comment", regex : "\\*\\/", next : "start"}, - {defaultToken : "comment"} - ] - }; - - this.embedRules(DocCommentHighlightRules, "doc-", [ DocCommentHighlightRules.getEndRule("start") ]); - this.normalizeRules(); -}; - -oop.inherits(MysqlHighlightRules, TextHighlightRules); - -exports.MysqlHighlightRules = MysqlHighlightRules; -}); - diff --git a/lib/ace/mode/nix.js b/lib/ace/mode/nix.js deleted file mode 100644 index 3048a569aed..00000000000 --- a/lib/ace/mode/nix.js +++ /dev/null @@ -1,63 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * Zef Hemel - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var CMode = require("./c_cpp").Mode; -var NixHighlightRules = require("./nix_highlight_rules").NixHighlightRules; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - CMode.call(this); - this.HighlightRules = NixHighlightRules; - this.foldingRules = new CStyleFoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, CMode); - -(function() { - this.lineCommentStart = "#"; - this.blockComment = {start: "/*", end: "*/"}; - this.$id = "ace/mode/nix"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/nsis.js b/lib/ace/mode/nsis.js deleted file mode 100644 index b20fce74873..00000000000 --- a/lib/ace/mode/nsis.js +++ /dev/null @@ -1,57 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var NSISHighlightRules = require("./nsis_highlight_rules").NSISHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = NSISHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = [";", "#"]; - this.blockComment = {start: "/*", end: "*/"}; - this.$id = "ace/mode/nsis"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/nsis_highlight_rules.js b/lib/ace/mode/nsis_highlight_rules.js deleted file mode 100644 index 3f27078517e..00000000000 --- a/lib/ace/mode/nsis_highlight_rules.js +++ /dev/null @@ -1,173 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var NSISHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { - start: [{ - token: "keyword.compiler.nsis", - regex: /^\s*!(?:include|addincludedir|addplugindir|appendfile|cd|delfile|echo|error|execute|packhdr|pragma|finalize|getdllversion|gettlbversion|system|tempfile|warning|verbose|define|undef|insertmacro|macro|macroend|makensis|searchparse|searchreplace)\b/, - caseInsensitive: true - }, { - token: "keyword.command.nsis", - 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|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|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|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEDllCharacteristics|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/, - caseInsensitive: true - }, { - token: "keyword.control.nsis", - regex: /^\s*!(?:ifdef|ifndef|if|ifmacrodef|ifmacrondef|else|endif)\b/, - caseInsensitive: true - }, { - token: "keyword.plugin.nsis", - regex: /^\s*\w+::\w+/, - caseInsensitive: true - }, { - token: "keyword.operator.comparison.nsis", - regex: /[!<>]?=|<>|<|>/ - }, { - token: "support.function.nsis", - regex: /(?:\b|^\s*)(?:Function|FunctionEnd|Section|SectionEnd|SectionGroup|SectionGroupEnd|PageEx|PageExEnd)\b/, - caseInsensitive: true - }, { - token: "support.library.nsis", - regex: /\${[\w\.:-]+}/ - }, { - token: "constant.nsis", - 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/, - caseInsensitive: true - }, { - token: "constant.library.nsis", - 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)}/ - }, { - token: "constant.language.boolean.true.nsis", - regex: /\b(?:true|on)\b/ - }, { - token: "constant.language.boolean.false.nsis", - regex: /\b(?:false|off)\b/ - }, { - token: "constant.language.option.nsis", - regex: /(?:\b|^\s*)(?:(?:un\.)?components|(?:un\.)?custom|(?:un\.)?directory|(?:un\.)?instfiles|(?:un\.)?license|uninstConfirm|admin|all|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|zlib)\b/, - caseInsensitive: true - }, { - token: "constant.language.slash-option.nsis", - 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/, - caseInsensitive: true - }, { - token: "constant.numeric.nsis", - regex: /\b(?:0(?:x|X)[0-9a-fA-F]+|[0-9]+(?:\.[0-9]+)?)\b/ - }, { - token: "entity.name.function.nsis", - regex: /\$\([\w\.:-]+\)/ - }, { - token: "storage.type.function.nsis", - regex: /\$\w+/ - }, { - token: "punctuation.definition.string.begin.nsis", - regex: /`/, - push: [{ - token: "punctuation.definition.string.end.nsis", - regex: /`/, - next: "pop" - }, { - token: "constant.character.escape.nsis", - regex: /\$\\./ - }, { - defaultToken: "string.quoted.back.nsis" - }] - }, { - token: "punctuation.definition.string.begin.nsis", - regex: /"/, - push: [{ - token: "punctuation.definition.string.end.nsis", - regex: /"/, - next: "pop" - }, { - token: "constant.character.escape.nsis", - regex: /\$\\./ - }, { - defaultToken: "string.quoted.double.nsis" - }] - }, { - token: "punctuation.definition.string.begin.nsis", - regex: /'/, - push: [{ - token: "punctuation.definition.string.end.nsis", - regex: /'/, - next: "pop" - }, { - token: "constant.character.escape.nsis", - regex: /\$\\./ - }, { - defaultToken: "string.quoted.single.nsis" - }] - }, { - token: [ - "punctuation.definition.comment.nsis", - "comment.line.nsis" - ], - regex: /(;|#)(.*$)/ - }, { - token: "punctuation.definition.comment.nsis", - regex: /\/\*/, - push: [{ - token: "punctuation.definition.comment.nsis", - regex: /\*\//, - next: "pop" - }, { - defaultToken: "comment.block.nsis" - }] - }, { - token: "text", - regex: /(?:!include|!insertmacro)\b/ - }] - }; - - this.normalizeRules(); -}; - -NSISHighlightRules.metaData = { - comment: "\n\ttodo: - highlight functions\n\t", - fileTypes: ["nsi", "nsh"], - name: "NSIS", - scopeName: "source.nsis" -}; - - -oop.inherits(NSISHighlightRules, TextHighlightRules); - -exports.NSISHighlightRules = NSISHighlightRules; -}); diff --git a/lib/ace/mode/objectivec.js b/lib/ace/mode/objectivec.js deleted file mode 100644 index be243606dce..00000000000 --- a/lib/ace/mode/objectivec.js +++ /dev/null @@ -1,62 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var ObjectiveCHighlightRules = require("./objectivec_highlight_rules").ObjectiveCHighlightRules; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = ObjectiveCHighlightRules; - this.foldingRules = new CStyleFoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; - this.$id = "ace/mode/objectivec"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/objectivec_highlight_rules.js b/lib/ace/mode/objectivec_highlight_rules.js deleted file mode 100644 index aded867d253..00000000000 --- a/lib/ace/mode/objectivec_highlight_rules.js +++ /dev/null @@ -1,330 +0,0 @@ -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; -var C_Highlight_File = require("./c_cpp_highlight_rules"); -var CHighlightRules = C_Highlight_File.c_cppHighlightRules; - -var ObjectiveCHighlightRules = function() { - - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - var escapedConstRe = "\\\\(?:[abefnrtv'\"?\\\\]|" + - "[0-3]\\d{1,2}|" + - "[4-7]\\d?|" + - "222|" + - "x[a-zA-Z0-9]+)"; - - var specialVariables = [{ - regex: "\\b_cmd\\b", - token: "variable.other.selector.objc" - }, { - regex: "\\b(?:self|super)\\b", - token: "variable.language.objc" - } - ]; - - var cObj = new CHighlightRules(); - var cRules = cObj.getRules(); - - this.$rules = { - "start": [ - { - token : "comment", - regex : "\\/\\/.*$" - }, - DocCommentHighlightRules.getStartRule("doc-start"), - { - token : "comment", // multi line comment - regex : "\\/\\*", - next : "comment" - }, - { - token: [ "storage.type.objc", "punctuation.definition.storage.type.objc", - "entity.name.type.objc", "text", "entity.other.inherited-class.objc" - ], - regex: "(@)(interface|protocol)(?!.+;)(\\s+[A-Za-z_][A-Za-z0-9_]*)(\\s*:\\s*)([A-Za-z]+)" - }, - { - token: [ "storage.type.objc" ], - regex: "(@end)" - }, - { - token: [ "storage.type.objc", "entity.name.type.objc", - "entity.other.inherited-class.objc" - ], - regex: "(@implementation)(\\s+[A-Za-z_][A-Za-z0-9_]*)(\\s*?::\\s*(?:[A-Za-z][A-Za-z0-9]*))?" - }, - { - token: "string.begin.objc", - regex: '@"', - next: "constant_NSString" - }, - { - token: "storage.type.objc", - regex: "\\bid\\s*<", - next: "protocol_list" - }, - { - token: "keyword.control.macro.objc", - regex: "\\bNS_DURING|NS_HANDLER|NS_ENDHANDLER\\b" - }, - { - token: ["punctuation.definition.keyword.objc", "keyword.control.exception.objc"], - regex: "(@)(try|catch|finally|throw)\\b" - }, - { - token: ["punctuation.definition.keyword.objc", "keyword.other.objc"], - regex: "(@)(defs|encode)\\b" - }, - { - token: ["storage.type.id.objc", "text"], - regex: "(\\bid\\b)(\\s|\\n)?" - }, - { - token: "storage.type.objc", - regex: "\\bIBOutlet|IBAction|BOOL|SEL|id|unichar|IMP|Class\\b" - }, - { - token: [ "punctuation.definition.storage.type.objc", "storage.type.objc"], - regex: "(@)(class|protocol)\\b" - }, - { - token: [ "punctuation.definition.storage.type.objc", "punctuation"], - regex: "(@selector)(\\s*\\()", - next: "selectors" - }, - { - token: [ "punctuation.definition.storage.modifier.objc", "storage.modifier.objc"], - regex: "(@)(synchronized|public|private|protected|package)\\b" - }, - { - token: "constant.language.objc", - regex: "\\bYES|NO|Nil|nil\\b" - }, - { - token: "support.variable.foundation", - regex: "\\bNSApp\\b" - }, - { - token: [ "support.function.cocoa.leopard"], - regex: "(?:\\b)(NS(?:Rect(?:ToCGRect|FromCGRect)|MakeCollectable|S(?:tringFromProtocol|ize(?:ToCGSize|FromCGSize))|Draw(?:NinePartImage|ThreePartImage)|P(?:oint(?:ToCGPoint|FromCGPoint)|rotocolFromString)|EventMaskFromType|Value))(?:\\b)" - }, - { - token: ["support.function.cocoa"], - regex: "(?:\\b)(NS(?:R(?:ound(?:DownToMultipleOfPageSize|UpToMultipleOfPageSize)|un(?:CriticalAlertPanel(?:RelativeToWindow)?|InformationalAlertPanel(?:RelativeToWindow)?|AlertPanel(?:RelativeToWindow)?)|e(?:set(?:MapTable|HashTable)|c(?:ycleZone|t(?:Clip(?:List)?|F(?:ill(?:UsingOperation|List(?:UsingOperation|With(?:Grays|Colors(?:UsingOperation)?))?)?|romString))|ordAllocationEvent)|turnAddress|leaseAlertPanel|a(?:dPixel|l(?:MemoryAvailable|locateCollectable))|gisterServicesProvider)|angeFromString)|Get(?:SizeAndAlignment|CriticalAlertPanel|InformationalAlertPanel|UncaughtExceptionHandler|FileType(?:s)?|WindowServerMemory|AlertPanel)|M(?:i(?:n(?:X|Y)|d(?:X|Y))|ouseInRect|a(?:p(?:Remove|Get|Member|Insert(?:IfAbsent|KnownAbsent)?)|ke(?:R(?:ect|ange)|Size|Point)|x(?:Range|X|Y)))|B(?:itsPer(?:SampleFromDepth|PixelFromDepth)|e(?:stDepth|ep|gin(?:CriticalAlertSheet|InformationalAlertSheet|AlertSheet)))|S(?:ho(?:uldRetainWithZone|w(?:sServicesMenuItem|AnimationEffect))|tringFrom(?:R(?:ect|ange)|MapTable|S(?:ize|elector)|HashTable|Class|Point)|izeFromString|e(?:t(?:ShowsServicesMenuItem|ZoneName|UncaughtExceptionHandler|FocusRingStyle)|lectorFromString|archPathForDirectoriesInDomains)|wap(?:Big(?:ShortToHost|IntToHost|DoubleToHost|FloatToHost|Long(?:ToHost|LongToHost))|Short|Host(?:ShortTo(?:Big|Little)|IntTo(?:Big|Little)|DoubleTo(?:Big|Little)|FloatTo(?:Big|Little)|Long(?:To(?:Big|Little)|LongTo(?:Big|Little)))|Int|Double|Float|L(?:ittle(?:ShortToHost|IntToHost|DoubleToHost|FloatToHost|Long(?:ToHost|LongToHost))|ong(?:Long)?)))|H(?:ighlightRect|o(?:stByteOrder|meDirectory(?:ForUser)?)|eight|ash(?:Remove|Get|Insert(?:IfAbsent|KnownAbsent)?)|FSType(?:CodeFromFileType|OfFile))|N(?:umberOfColorComponents|ext(?:MapEnumeratorPair|HashEnumeratorItem))|C(?:o(?:n(?:tainsRect|vert(?:GlyphsToPackedGlyphs|Swapped(?:DoubleToHost|FloatToHost)|Host(?:DoubleToSwapped|FloatToSwapped)))|unt(?:MapTable|HashTable|Frames|Windows(?:ForContext)?)|py(?:M(?:emoryPages|apTableWithZone)|Bits|HashTableWithZone|Object)|lorSpaceFromDepth|mpare(?:MapTables|HashTables))|lassFromString|reate(?:MapTable(?:WithZone)?|HashTable(?:WithZone)?|Zone|File(?:namePboardType|ContentsPboardType)))|TemporaryDirectory|I(?:s(?:ControllerMarker|EmptyRect|FreedObject)|n(?:setRect|crementExtraRefCount|te(?:r(?:sect(?:sRect|ionR(?:ect|ange))|faceStyleForKey)|gralRect)))|Zone(?:Realloc|Malloc|Name|Calloc|Fr(?:omPointer|ee))|O(?:penStepRootDirectory|ffsetRect)|D(?:i(?:sableScreenUpdates|videRect)|ottedFrameRect|e(?:c(?:imal(?:Round|Multiply|S(?:tring|ubtract)|Normalize|Co(?:py|mpa(?:ct|re))|IsNotANumber|Divide|Power|Add)|rementExtraRefCountWasZero)|faultMallocZone|allocate(?:MemoryPages|Object))|raw(?:Gr(?:oove|ayBezel)|B(?:itmap|utton)|ColorTiledRects|TiledRects|DarkBezel|W(?:hiteBezel|indowBackground)|LightBezel))|U(?:serName|n(?:ionR(?:ect|ange)|registerServicesProvider)|pdateDynamicServices)|Java(?:Bundle(?:Setup|Cleanup)|Setup(?:VirtualMachine)?|Needs(?:ToLoadClasses|VirtualMachine)|ClassesF(?:orBundle|romPath)|ObjectNamedInPath|ProvidesClasses)|P(?:oint(?:InRect|FromString)|erformService|lanarFromDepth|ageSize)|E(?:n(?:d(?:MapTableEnumeration|HashTableEnumeration)|umerate(?:MapTable|HashTable)|ableScreenUpdates)|qual(?:R(?:ects|anges)|Sizes|Points)|raseRect|xtraRefCount)|F(?:ileTypeForHFSTypeCode|ullUserName|r(?:ee(?:MapTable|HashTable)|ame(?:Rect(?:WithWidth(?:UsingOperation)?)?|Address)))|Wi(?:ndowList(?:ForContext)?|dth)|Lo(?:cationInRange|g(?:v|PageSize)?)|A(?:ccessibility(?:R(?:oleDescription(?:ForUIElement)?|aiseBadArgumentException)|Unignored(?:Children(?:ForOnlyChild)?|Descendant|Ancestor)|PostNotification|ActionDescription)|pplication(?:Main|Load)|vailableWindowDepths|ll(?:MapTable(?:Values|Keys)|HashTableObjects|ocate(?:MemoryPages|Collectable|Object)))))(?:\\b)" - }, - { - token: ["support.class.cocoa.leopard"], - regex: "(?:\\b)(NS(?:RuleEditor|G(?:arbageCollector|radient)|MapTable|HashTable|Co(?:ndition|llectionView(?:Item)?)|T(?:oolbarItemGroup|extInputClient|r(?:eeNode|ackingArea))|InvocationOperation|Operation(?:Queue)?|D(?:ictionaryController|ockTile)|P(?:ointer(?:Functions|Array)|athC(?:o(?:ntrol(?:Delegate)?|mponentCell)|ell(?:Delegate)?)|r(?:intPanelAccessorizing|edicateEditor(?:RowTemplate)?))|ViewController|FastEnumeration|Animat(?:ionContext|ablePropertyContainer)))(?:\\b)" - }, - { - token: ["support.class.cocoa"], - regex: "(?:\\b)(NS(?:R(?:u(?:nLoop|ler(?:Marker|View))|e(?:sponder|cursiveLock|lativeSpecifier)|an(?:domSpecifier|geSpecifier))|G(?:etCommand|lyph(?:Generator|Storage|Info)|raphicsContext)|XML(?:Node|D(?:ocument|TD(?:Node)?)|Parser|Element)|M(?:iddleSpecifier|ov(?:ie(?:View)?|eCommand)|utable(?:S(?:tring|et)|C(?:haracterSet|opying)|IndexSet|D(?:ictionary|ata)|URLRequest|ParagraphStyle|A(?:ttributedString|rray))|e(?:ssagePort(?:NameServer)?|nu(?:Item(?:Cell)?|View)?|t(?:hodSignature|adata(?:Item|Query(?:ResultGroup|AttributeValueTuple)?)))|a(?:ch(?:BootstrapServer|Port)|trix))|B(?:itmapImageRep|ox|u(?:ndle|tton(?:Cell)?)|ezierPath|rowser(?:Cell)?)|S(?:hadow|c(?:anner|r(?:ipt(?:SuiteRegistry|C(?:o(?:ercionHandler|mmand(?:Description)?)|lassDescription)|ObjectSpecifier|ExecutionContext|WhoseTest)|oll(?:er|View)|een))|t(?:epper(?:Cell)?|atus(?:Bar|Item)|r(?:ing|eam))|imple(?:HorizontalTypesetter|CString)|o(?:cketPort(?:NameServer)?|und|rtDescriptor)|p(?:e(?:cifierTest|ech(?:Recognizer|Synthesizer)|ll(?:Server|Checker))|litView)|e(?:cureTextField(?:Cell)?|t(?:Command)?|archField(?:Cell)?|rializer|gmentedC(?:ontrol|ell))|lider(?:Cell)?|avePanel)|H(?:ost|TTP(?:Cookie(?:Storage)?|URLResponse)|elpManager)|N(?:ib(?:Con(?:nector|trolConnector)|OutletConnector)?|otification(?:Center|Queue)?|u(?:ll|mber(?:Formatter)?)|etService(?:Browser)?|ameSpecifier)|C(?:ha(?:ngeSpelling|racterSet)|o(?:n(?:stantString|nection|trol(?:ler)?|ditionLock)|d(?:ing|er)|unt(?:Command|edSet)|pying|lor(?:Space|P(?:ick(?:ing(?:Custom|Default)|er)|anel)|Well|List)?|m(?:p(?:oundPredicate|arisonPredicate)|boBox(?:Cell)?))|u(?:stomImageRep|rsor)|IImageRep|ell|l(?:ipView|o(?:seCommand|neCommand)|assDescription)|a(?:ched(?:ImageRep|URLResponse)|lendar(?:Date)?)|reateCommand)|T(?:hread|ypesetter|ime(?:Zone|r)|o(?:olbar(?:Item(?:Validations)?)?|kenField(?:Cell)?)|ext(?:Block|Storage|Container|Tab(?:le(?:Block)?)?|Input|View|Field(?:Cell)?|List|Attachment(?:Cell)?)?|a(?:sk|b(?:le(?:Header(?:Cell|View)|Column|View)|View(?:Item)?))|reeController)|I(?:n(?:dex(?:S(?:pecifier|et)|Path)|put(?:Manager|S(?:tream|erv(?:iceProvider|er(?:MouseTracker)?)))|vocation)|gnoreMisspelledWords|mage(?:Rep|Cell|View)?)|O(?:ut(?:putStream|lineView)|pen(?:GL(?:Context|Pixel(?:Buffer|Format)|View)|Panel)|bj(?:CTypeSerializationCallBack|ect(?:Controller)?))|D(?:i(?:st(?:antObject(?:Request)?|ributed(?:NotificationCenter|Lock))|ctionary|rectoryEnumerator)|ocument(?:Controller)?|e(?:serializer|cimalNumber(?:Behaviors|Handler)?|leteCommand)|at(?:e(?:Components|Picker(?:Cell)?|Formatter)?|a)|ra(?:wer|ggingInfo))|U(?:ser(?:InterfaceValidations|Defaults(?:Controller)?)|RL(?:Re(?:sponse|quest)|Handle(?:Client)?|C(?:onnection|ache|redential(?:Storage)?)|Download(?:Delegate)?|Prot(?:ocol(?:Client)?|ectionSpace)|AuthenticationChallenge(?:Sender)?)?|n(?:iqueIDSpecifier|doManager|archiver))|P(?:ipe|o(?:sitionalSpecifier|pUpButton(?:Cell)?|rt(?:Message|NameServer|Coder)?)|ICTImageRep|ersistentDocument|DFImageRep|a(?:steboard|nel|ragraphStyle|geLayout)|r(?:int(?:Info|er|Operation|Panel)|o(?:cessInfo|tocolChecker|perty(?:Specifier|ListSerialization)|gressIndicator|xy)|edicate))|E(?:numerator|vent|PSImageRep|rror|x(?:ception|istsCommand|pression))|V(?:iew(?:Animation)?|al(?:idated(?:ToobarItem|UserInterfaceItem)|ue(?:Transformer)?))|Keyed(?:Unarchiver|Archiver)|Qui(?:ckDrawView|tCommand)|F(?:ile(?:Manager|Handle|Wrapper)|o(?:nt(?:Manager|Descriptor|Panel)?|rm(?:Cell|atter)))|W(?:hoseSpecifier|indow(?:Controller)?|orkspace)|L(?:o(?:c(?:k(?:ing)?|ale)|gicalTest)|evelIndicator(?:Cell)?|ayoutManager)|A(?:ssertionHandler|nimation|ctionCell|ttributedString|utoreleasePool|TSTypesetter|ppl(?:ication|e(?:Script|Event(?:Manager|Descriptor)))|ffineTransform|lert|r(?:chiver|ray(?:Controller)?))))(?:\\b)" - }, - { - token: ["support.type.cocoa.leopard"], - regex: "(?:\\b)(NS(?:R(?:u(?:nLoop|ler(?:Marker|View))|e(?:sponder|cursiveLock|lativeSpecifier)|an(?:domSpecifier|geSpecifier))|G(?:etCommand|lyph(?:Generator|Storage|Info)|raphicsContext)|XML(?:Node|D(?:ocument|TD(?:Node)?)|Parser|Element)|M(?:iddleSpecifier|ov(?:ie(?:View)?|eCommand)|utable(?:S(?:tring|et)|C(?:haracterSet|opying)|IndexSet|D(?:ictionary|ata)|URLRequest|ParagraphStyle|A(?:ttributedString|rray))|e(?:ssagePort(?:NameServer)?|nu(?:Item(?:Cell)?|View)?|t(?:hodSignature|adata(?:Item|Query(?:ResultGroup|AttributeValueTuple)?)))|a(?:ch(?:BootstrapServer|Port)|trix))|B(?:itmapImageRep|ox|u(?:ndle|tton(?:Cell)?)|ezierPath|rowser(?:Cell)?)|S(?:hadow|c(?:anner|r(?:ipt(?:SuiteRegistry|C(?:o(?:ercionHandler|mmand(?:Description)?)|lassDescription)|ObjectSpecifier|ExecutionContext|WhoseTest)|oll(?:er|View)|een))|t(?:epper(?:Cell)?|atus(?:Bar|Item)|r(?:ing|eam))|imple(?:HorizontalTypesetter|CString)|o(?:cketPort(?:NameServer)?|und|rtDescriptor)|p(?:e(?:cifierTest|ech(?:Recognizer|Synthesizer)|ll(?:Server|Checker))|litView)|e(?:cureTextField(?:Cell)?|t(?:Command)?|archField(?:Cell)?|rializer|gmentedC(?:ontrol|ell))|lider(?:Cell)?|avePanel)|H(?:ost|TTP(?:Cookie(?:Storage)?|URLResponse)|elpManager)|N(?:ib(?:Con(?:nector|trolConnector)|OutletConnector)?|otification(?:Center|Queue)?|u(?:ll|mber(?:Formatter)?)|etService(?:Browser)?|ameSpecifier)|C(?:ha(?:ngeSpelling|racterSet)|o(?:n(?:stantString|nection|trol(?:ler)?|ditionLock)|d(?:ing|er)|unt(?:Command|edSet)|pying|lor(?:Space|P(?:ick(?:ing(?:Custom|Default)|er)|anel)|Well|List)?|m(?:p(?:oundPredicate|arisonPredicate)|boBox(?:Cell)?))|u(?:stomImageRep|rsor)|IImageRep|ell|l(?:ipView|o(?:seCommand|neCommand)|assDescription)|a(?:ched(?:ImageRep|URLResponse)|lendar(?:Date)?)|reateCommand)|T(?:hread|ypesetter|ime(?:Zone|r)|o(?:olbar(?:Item(?:Validations)?)?|kenField(?:Cell)?)|ext(?:Block|Storage|Container|Tab(?:le(?:Block)?)?|Input|View|Field(?:Cell)?|List|Attachment(?:Cell)?)?|a(?:sk|b(?:le(?:Header(?:Cell|View)|Column|View)|View(?:Item)?))|reeController)|I(?:n(?:dex(?:S(?:pecifier|et)|Path)|put(?:Manager|S(?:tream|erv(?:iceProvider|er(?:MouseTracker)?)))|vocation)|gnoreMisspelledWords|mage(?:Rep|Cell|View)?)|O(?:ut(?:putStream|lineView)|pen(?:GL(?:Context|Pixel(?:Buffer|Format)|View)|Panel)|bj(?:CTypeSerializationCallBack|ect(?:Controller)?))|D(?:i(?:st(?:antObject(?:Request)?|ributed(?:NotificationCenter|Lock))|ctionary|rectoryEnumerator)|ocument(?:Controller)?|e(?:serializer|cimalNumber(?:Behaviors|Handler)?|leteCommand)|at(?:e(?:Components|Picker(?:Cell)?|Formatter)?|a)|ra(?:wer|ggingInfo))|U(?:ser(?:InterfaceValidations|Defaults(?:Controller)?)|RL(?:Re(?:sponse|quest)|Handle(?:Client)?|C(?:onnection|ache|redential(?:Storage)?)|Download(?:Delegate)?|Prot(?:ocol(?:Client)?|ectionSpace)|AuthenticationChallenge(?:Sender)?)?|n(?:iqueIDSpecifier|doManager|archiver))|P(?:ipe|o(?:sitionalSpecifier|pUpButton(?:Cell)?|rt(?:Message|NameServer|Coder)?)|ICTImageRep|ersistentDocument|DFImageRep|a(?:steboard|nel|ragraphStyle|geLayout)|r(?:int(?:Info|er|Operation|Panel)|o(?:cessInfo|tocolChecker|perty(?:Specifier|ListSerialization)|gressIndicator|xy)|edicate))|E(?:numerator|vent|PSImageRep|rror|x(?:ception|istsCommand|pression))|V(?:iew(?:Animation)?|al(?:idated(?:ToobarItem|UserInterfaceItem)|ue(?:Transformer)?))|Keyed(?:Unarchiver|Archiver)|Qui(?:ckDrawView|tCommand)|F(?:ile(?:Manager|Handle|Wrapper)|o(?:nt(?:Manager|Descriptor|Panel)?|rm(?:Cell|atter)))|W(?:hoseSpecifier|indow(?:Controller)?|orkspace)|L(?:o(?:c(?:k(?:ing)?|ale)|gicalTest)|evelIndicator(?:Cell)?|ayoutManager)|A(?:ssertionHandler|nimation|ctionCell|ttributedString|utoreleasePool|TSTypesetter|ppl(?:ication|e(?:Script|Event(?:Manager|Descriptor)))|ffineTransform|lert|r(?:chiver|ray(?:Controller)?))))(?:\\b)" - }, - { - token: ["support.class.quartz"], - regex: "(?:\\b)(C(?:I(?:Sampler|Co(?:ntext|lor)|Image(?:Accumulator)?|PlugIn(?:Registration)?|Vector|Kernel|Filter(?:Generator|Shape)?)|A(?:Renderer|MediaTiming(?:Function)?|BasicAnimation|ScrollLayer|Constraint(?:LayoutManager)?|T(?:iledLayer|extLayer|rans(?:ition|action))|OpenGLLayer|PropertyAnimation|KeyframeAnimation|Layer|A(?:nimation(?:Group)?|ction))))(?:\\b)" - }, - { - token: ["support.type.quartz"], - regex: "(?:\\b)(C(?:G(?:Float|Point|Size|Rect)|IFormat|AConstraintAttribute))(?:\\b)" - }, - { - token: ["support.type.cocoa"], - regex: "(?:\\b)(NS(?:R(?:ect(?:Edge)?|ange)|G(?:lyph(?:Relation|LayoutMode)?|radientType)|M(?:odalSession|a(?:trixMode|p(?:Table|Enumerator)))|B(?:itmapImageFileType|orderType|uttonType|ezelStyle|ackingStoreType|rowserColumnResizingType)|S(?:cr(?:oll(?:er(?:Part|Arrow)|ArrowPosition)|eenAuxiliaryOpaque)|tringEncoding|ize|ocketNativeHandle|election(?:Granularity|Direction|Affinity)|wapped(?:Double|Float)|aveOperationType)|Ha(?:sh(?:Table|Enumerator)|ndler(?:2)?)|C(?:o(?:ntrol(?:Size|Tint)|mp(?:ositingOperation|arisonResult))|ell(?:State|Type|ImagePosition|Attribute))|T(?:hreadPrivate|ypesetterGlyphInfo|i(?:ckMarkPosition|tlePosition|meInterval)|o(?:ol(?:TipTag|bar(?:SizeMode|DisplayMode))|kenStyle)|IFFCompression|ext(?:TabType|Alignment)|ab(?:State|leViewDropOperation|ViewType)|rackingRectTag)|ImageInterpolation|Zone|OpenGL(?:ContextAuxiliary|PixelFormatAuxiliary)|D(?:ocumentChangeType|atePickerElementFlags|ra(?:werState|gOperation))|UsableScrollerParts|P(?:oint|r(?:intingPageOrder|ogressIndicator(?:Style|Th(?:ickness|readInfo))))|EventType|KeyValueObservingOptions|Fo(?:nt(?:SymbolicTraits|TraitMask|Action)|cusRingType)|W(?:indow(?:OrderingMode|Depth)|orkspace(?:IconCreationOptions|LaunchOptions)|ritingDirection)|L(?:ineBreakMode|ayout(?:Status|Direction))|A(?:nimation(?:Progress|Effect)|ppl(?:ication(?:TerminateReply|DelegateReply|PrintReply)|eEventManagerSuspensionID)|ffineTransformStruct|lertStyle)))(?:\\b)" - }, - { - token: ["support.constant.cocoa"], - regex: "(?:\\b)(NS(?:NotFound|Ordered(?:Ascending|Descending|Same)))(?:\\b)" - }, - { - token: ["support.constant.notification.cocoa.leopard"], - regex: "(?:\\b)(NS(?:MenuDidBeginTracking|ViewDidUpdateTrackingAreas)?Notification)(?:\\b)" - }, - { - token: ["support.constant.notification.cocoa"], - regex: "(?:\\b)(NS(?:Menu(?:Did(?:RemoveItem|SendAction|ChangeItem|EndTracking|AddItem)|WillSendAction)|S(?:ystemColorsDidChange|plitView(?:DidResizeSubviews|WillResizeSubviews))|C(?:o(?:nt(?:extHelpModeDid(?:Deactivate|Activate)|rolT(?:intDidChange|extDid(?:BeginEditing|Change|EndEditing)))|lor(?:PanelColorDidChange|ListDidChange)|mboBox(?:Selection(?:IsChanging|DidChange)|Will(?:Dismiss|PopUp)))|lassDescriptionNeededForClass)|T(?:oolbar(?:DidRemoveItem|WillAddItem)|ext(?:Storage(?:DidProcessEditing|WillProcessEditing)|Did(?:BeginEditing|Change|EndEditing)|View(?:DidChange(?:Selection|TypingAttributes)|WillChangeNotifyingTextView))|ableView(?:Selection(?:IsChanging|DidChange)|ColumnDid(?:Resize|Move)))|ImageRepRegistryDidChange|OutlineView(?:Selection(?:IsChanging|DidChange)|ColumnDid(?:Resize|Move)|Item(?:Did(?:Collapse|Expand)|Will(?:Collapse|Expand)))|Drawer(?:Did(?:Close|Open)|Will(?:Close|Open))|PopUpButton(?:CellWillPopUp|WillPopUp)|View(?:GlobalFrameDidChange|BoundsDidChange|F(?:ocusDidChange|rameDidChange))|FontSetChanged|W(?:indow(?:Did(?:Resi(?:ze|gn(?:Main|Key))|M(?:iniaturize|ove)|Become(?:Main|Key)|ChangeScreen(?:|Profile)|Deminiaturize|Update|E(?:ndSheet|xpose))|Will(?:M(?:iniaturize|ove)|BeginSheet|Close))|orkspace(?:SessionDid(?:ResignActive|BecomeActive)|Did(?:Mount|TerminateApplication|Unmount|PerformFileOperation|Wake|LaunchApplication)|Will(?:Sleep|Unmount|PowerOff|LaunchApplication)))|A(?:ntialiasThresholdChanged|ppl(?:ication(?:Did(?:ResignActive|BecomeActive|Hide|ChangeScreenParameters|U(?:nhide|pdate)|FinishLaunching)|Will(?:ResignActive|BecomeActive|Hide|Terminate|U(?:nhide|pdate)|FinishLaunching))|eEventManagerWillProcessFirstEvent)))Notification)(?:\\b)" - }, - { - token: ["support.constant.cocoa.leopard"], - regex: "(?:\\b)(NS(?:RuleEditor(?:RowType(?:Simple|Compound)|NestingMode(?:Si(?:ngle|mple)|Compound|List))|GradientDraws(?:BeforeStartingLocation|AfterEndingLocation)|M(?:inusSetExpressionType|a(?:chPortDeallocate(?:ReceiveRight|SendRight|None)|pTable(?:StrongMemory|CopyIn|ZeroingWeakMemory|ObjectPointerPersonality)))|B(?:oxCustom|undleExecutableArchitecture(?:X86|I386|PPC(?:64)?)|etweenPredicateOperatorType|ackgroundStyle(?:Raised|Dark|L(?:ight|owered)))|S(?:tring(?:DrawingTruncatesLastVisibleLine|EncodingConversion(?:ExternalRepresentation|AllowLossy))|ubqueryExpressionType|p(?:e(?:ech(?:SentenceBoundary|ImmediateBoundary|WordBoundary)|llingState(?:GrammarFlag|SpellingFlag))|litViewDividerStyleThi(?:n|ck))|e(?:rvice(?:RequestTimedOutError|M(?:iscellaneousError|alformedServiceDictionaryError)|InvalidPasteboardDataError|ErrorM(?:inimum|aximum)|Application(?:NotFoundError|LaunchFailedError))|gmentStyle(?:Round(?:Rect|ed)|SmallSquare|Capsule|Textured(?:Rounded|Square)|Automatic)))|H(?:UDWindowMask|ashTable(?:StrongMemory|CopyIn|ZeroingWeakMemory|ObjectPointerPersonality))|N(?:oModeColorPanel|etServiceNoAutoRename)|C(?:hangeRedone|o(?:ntainsPredicateOperatorType|l(?:orRenderingIntent(?:RelativeColorimetric|Saturation|Default|Perceptual|AbsoluteColorimetric)|lectorDisabledOption))|ellHit(?:None|ContentArea|TrackableArea|EditableTextArea))|T(?:imeZoneNameStyle(?:S(?:hort(?:Standard|DaylightSaving)|tandard)|DaylightSaving)|extFieldDatePickerStyle|ableViewSelectionHighlightStyle(?:Regular|SourceList)|racking(?:Mouse(?:Moved|EnteredAndExited)|CursorUpdate|InVisibleRect|EnabledDuringMouseDrag|A(?:ssumeInside|ctive(?:In(?:KeyWindow|ActiveApp)|WhenFirstResponder|Always))))|I(?:n(?:tersectSetExpressionType|dexedColorSpaceModel)|mageScale(?:None|Proportionally(?:Down|UpOrDown)|AxesIndependently))|Ope(?:nGLPFAAllowOfflineRenderers|rationQueue(?:DefaultMaxConcurrentOperationCount|Priority(?:High|Normal|Very(?:High|Low)|Low)))|D(?:iacriticInsensitiveSearch|ownloadsDirectory)|U(?:nionSetExpressionType|TF(?:16(?:BigEndianStringEncoding|StringEncoding|LittleEndianStringEncoding)|32(?:BigEndianStringEncoding|StringEncoding|LittleEndianStringEncoding)))|P(?:ointerFunctions(?:Ma(?:chVirtualMemory|llocMemory)|Str(?:ongMemory|uctPersonality)|C(?:StringPersonality|opyIn)|IntegerPersonality|ZeroingWeakMemory|O(?:paque(?:Memory|Personality)|bjectP(?:ointerPersonality|ersonality)))|at(?:hStyle(?:Standard|NavigationBar|PopUp)|ternColorSpaceModel)|rintPanelShows(?:Scaling|Copies|Orientation|P(?:a(?:perSize|ge(?:Range|SetupAccessory))|review)))|Executable(?:RuntimeMismatchError|NotLoadableError|ErrorM(?:inimum|aximum)|L(?:inkError|oadError)|ArchitectureMismatchError)|KeyValueObservingOption(?:Initial|Prior)|F(?:i(?:ndPanelSubstringMatchType(?:StartsWith|Contains|EndsWith|FullWord)|leRead(?:TooLargeError|UnknownStringEncodingError))|orcedOrderingSearch)|Wi(?:ndow(?:BackingLocation(?:MainMemory|Default|VideoMemory)|Sharing(?:Read(?:Only|Write)|None)|CollectionBehavior(?:MoveToActiveSpace|CanJoinAllSpaces|Default))|dthInsensitiveSearch)|AggregateExpressionType))(?:\\b)" - }, - { - token: ["support.constant.cocoa"], - regex: "(?:\\b)(NS(?:R(?:GB(?:ModeColorPanel|ColorSpaceModel)|ight(?:Mouse(?:D(?:own(?:Mask)?|ragged(?:Mask)?)|Up(?:Mask)?)|T(?:ext(?:Movement|Alignment)|ab(?:sBezelBorder|StopType))|ArrowFunctionKey)|ound(?:RectBezelStyle|Bankers|ed(?:BezelStyle|TokenStyle|DisclosureBezelStyle)|Down|Up|Plain|Line(?:CapStyle|JoinStyle))|un(?:StoppedResponse|ContinuesResponse|AbortedResponse)|e(?:s(?:izableWindowMask|et(?:CursorRectsRunLoopOrdering|FunctionKey))|ce(?:ssedBezelStyle|iver(?:sCantHandleCommandScriptError|EvaluationScriptError))|turnTextMovement|doFunctionKey|quiredArgumentsMissingScriptError|l(?:evancyLevelIndicatorStyle|ative(?:Before|After))|gular(?:SquareBezelStyle|ControlSize)|moveTraitFontAction)|a(?:n(?:domSubelement|geDateMode)|tingLevelIndicatorStyle|dio(?:ModeMatrix|Button)))|G(?:IFFileType|lyph(?:Below|Inscribe(?:B(?:elow|ase)|Over(?:strike|Below)|Above)|Layout(?:WithPrevious|A(?:tAPoint|gainstAPoint))|A(?:ttribute(?:BidiLevel|Soft|Inscribe|Elastic)|bove))|r(?:ooveBorder|eaterThan(?:Comparison|OrEqualTo(?:Comparison|PredicateOperatorType)|PredicateOperatorType)|a(?:y(?:ModeColorPanel|ColorSpaceModel)|dient(?:None|Con(?:cave(?:Strong|Weak)|vex(?:Strong|Weak)))|phiteControlTint)))|XML(?:N(?:o(?:tationDeclarationKind|de(?:CompactEmptyElement|IsCDATA|OptionsNone|Use(?:SingleQuotes|DoubleQuotes)|Pre(?:serve(?:NamespaceOrder|C(?:haracterReferences|DATA)|DTD|Prefixes|E(?:ntities|mptyElements)|Quotes|Whitespace|A(?:ttributeOrder|ll))|ttyPrint)|ExpandEmptyElement))|amespaceKind)|CommentKind|TextKind|InvalidKind|D(?:ocument(?:X(?:MLKind|HTMLKind|Include)|HTMLKind|T(?:idy(?:XML|HTML)|extKind)|IncludeContentTypeDeclaration|Validate|Kind)|TDKind)|P(?:arser(?:GTRequiredError|XMLDeclNot(?:StartedError|FinishedError)|Mi(?:splaced(?:XMLDeclarationError|CDATAEndStringError)|xedContentDeclNot(?:StartedError|FinishedError))|S(?:t(?:andaloneValueError|ringNot(?:StartedError|ClosedError))|paceRequiredError|eparatorRequiredError)|N(?:MTOKENRequiredError|o(?:t(?:ationNot(?:StartedError|FinishedError)|WellBalancedError)|DTDError)|amespaceDeclarationError|AMERequiredError)|C(?:haracterRef(?:In(?:DTDError|PrologError|EpilogError)|AtEOFError)|o(?:nditionalSectionNot(?:StartedError|FinishedError)|mment(?:NotFinishedError|ContainsDoubleHyphenError))|DATANotFinishedError)|TagNameMismatchError|In(?:ternalError|valid(?:HexCharacterRefError|C(?:haracter(?:RefError|InEntityError|Error)|onditionalSectionError)|DecimalCharacterRefError|URIError|Encoding(?:NameError|Error)))|OutOfMemoryError|D(?:ocumentStartError|elegateAbortedParseError|OCTYPEDeclNotFinishedError)|U(?:RI(?:RequiredError|FragmentError)|n(?:declaredEntityError|parsedEntityError|knownEncodingError|finishedTagError))|P(?:CDATARequiredError|ublicIdentifierRequiredError|arsedEntityRef(?:MissingSemiError|NoNameError|In(?:Internal(?:SubsetError|Error)|PrologError|EpilogError)|AtEOFError)|r(?:ocessingInstructionNot(?:StartedError|FinishedError)|ematureDocumentEndError))|E(?:n(?:codingNotSupportedError|tity(?:Ref(?:In(?:DTDError|PrologError|EpilogError)|erence(?:MissingSemiError|WithoutNameError)|LoopError|AtEOFError)|BoundaryError|Not(?:StartedError|FinishedError)|Is(?:ParameterError|ExternalError)|ValueRequiredError))|qualExpectedError|lementContentDeclNot(?:StartedError|FinishedError)|xt(?:ernalS(?:tandaloneEntityError|ubsetNotFinishedError)|raContentError)|mptyDocumentError)|L(?:iteralNot(?:StartedError|FinishedError)|T(?:RequiredError|SlashRequiredError)|essThanSymbolInAttributeError)|Attribute(?:RedefinedError|HasNoValueError|Not(?:StartedError|FinishedError)|ListNot(?:StartedError|FinishedError)))|rocessingInstructionKind)|E(?:ntity(?:GeneralKind|DeclarationKind|UnparsedKind|P(?:ar(?:sedKind|ameterKind)|redefined))|lement(?:Declaration(?:MixedKind|UndefinedKind|E(?:lementKind|mptyKind)|Kind|AnyKind)|Kind))|Attribute(?:N(?:MToken(?:sKind|Kind)|otationKind)|CDATAKind|ID(?:Ref(?:sKind|Kind)|Kind)|DeclarationKind|En(?:tit(?:yKind|iesKind)|umerationKind)|Kind))|M(?:i(?:n(?:XEdge|iaturizableWindowMask|YEdge|uteCalendarUnit)|terLineJoinStyle|ddleSubelement|xedState)|o(?:nthCalendarUnit|deSwitchFunctionKey|use(?:Moved(?:Mask)?|E(?:ntered(?:Mask)?|ventSubtype|xited(?:Mask)?))|veToBezierPathElement|mentary(?:ChangeButton|Push(?:Button|InButton)|Light(?:Button)?))|enuFunctionKey|a(?:c(?:intoshInterfaceStyle|OSRomanStringEncoding)|tchesPredicateOperatorType|ppedRead|x(?:XEdge|YEdge))|ACHOperatingSystem)|B(?:MPFileType|o(?:ttomTabsBezelBorder|ldFontMask|rderlessWindowMask|x(?:Se(?:condary|parator)|OldStyle|Primary))|uttLineCapStyle|e(?:zelBorder|velLineJoinStyle|low(?:Bottom|Top)|gin(?:sWith(?:Comparison|PredicateOperatorType)|FunctionKey))|lueControlTint|ack(?:spaceCharacter|tabTextMovement|ingStore(?:Retained|Buffered|Nonretained)|TabCharacter|wardsSearch|groundTab)|r(?:owser(?:NoColumnResizing|UserColumnResizing|AutoColumnResizing)|eakFunctionKey))|S(?:h(?:ift(?:JISStringEncoding|KeyMask)|ow(?:ControlGlyphs|InvisibleGlyphs)|adowlessSquareBezelStyle)|y(?:s(?:ReqFunctionKey|tem(?:D(?:omainMask|efined(?:Mask)?)|FunctionKey))|mbolStringEncoding)|c(?:a(?:nnedOption|le(?:None|ToFit|Proportionally))|r(?:oll(?:er(?:NoPart|Increment(?:Page|Line|Arrow)|Decrement(?:Page|Line|Arrow)|Knob(?:Slot)?|Arrows(?:M(?:inEnd|axEnd)|None|DefaultSetting))|Wheel(?:Mask)?|LockFunctionKey)|eenChangedEventType))|t(?:opFunctionKey|r(?:ingDrawing(?:OneShot|DisableScreenFontSubstitution|Uses(?:DeviceMetrics|FontLeading|LineFragmentOrigin))|eam(?:Status(?:Reading|NotOpen|Closed|Open(?:ing)?|Error|Writing|AtEnd)|Event(?:Has(?:BytesAvailable|SpaceAvailable)|None|OpenCompleted|E(?:ndEncountered|rrorOccurred)))))|i(?:ngle(?:DateMode|UnderlineStyle)|ze(?:DownFontAction|UpFontAction))|olarisOperatingSystem|unOSOperatingSystem|pecialPageOrder|e(?:condCalendarUnit|lect(?:By(?:Character|Paragraph|Word)|i(?:ng(?:Next|Previous)|onAffinity(?:Downstream|Upstream))|edTab|FunctionKey)|gmentSwitchTracking(?:Momentary|Select(?:One|Any)))|quareLineCapStyle|witchButton|ave(?:ToOperation|Op(?:tions(?:Yes|No|Ask)|eration)|AsOperation)|mall(?:SquareBezelStyle|C(?:ontrolSize|apsFontMask)|IconButtonBezelStyle))|H(?:ighlightModeMatrix|SBModeColorPanel|o(?:ur(?:Minute(?:SecondDatePickerElementFlag|DatePickerElementFlag)|CalendarUnit)|rizontalRuler|meFunctionKey)|TTPCookieAcceptPolicy(?:Never|OnlyFromMainDocumentDomain|Always)|e(?:lp(?:ButtonBezelStyle|KeyMask|FunctionKey)|avierFontAction)|PUXOperatingSystem)|Year(?:MonthDa(?:yDatePickerElementFlag|tePickerElementFlag)|CalendarUnit)|N(?:o(?:n(?:StandardCharacterSetFontMask|ZeroWindingRule|activatingPanelMask|LossyASCIIStringEncoding)|Border|t(?:ification(?:SuspensionBehavior(?:Hold|Coalesce|D(?:eliverImmediately|rop))|NoCoalescing|CoalescingOn(?:Sender|Name)|DeliverImmediately|PostToAllSessions)|PredicateType|EqualToPredicateOperatorType)|S(?:cr(?:iptError|ollerParts)|ubelement|pecifierError)|CellMask|T(?:itle|opLevelContainersSpecifierError|abs(?:BezelBorder|NoBorder|LineBorder))|I(?:nterfaceStyle|mage)|UnderlineStyle|FontChangeAction)|u(?:ll(?:Glyph|CellType)|m(?:eric(?:Search|PadKeyMask)|berFormatter(?:Round(?:Half(?:Down|Up|Even)|Ceiling|Down|Up|Floor)|Behavior(?:10|Default)|S(?:cientificStyle|pellOutStyle)|NoStyle|CurrencyStyle|DecimalStyle|P(?:ercentStyle|ad(?:Before(?:Suffix|Prefix)|After(?:Suffix|Prefix))))))|e(?:t(?:Services(?:BadArgumentError|NotFoundError|C(?:ollisionError|ancelledError)|TimeoutError|InvalidError|UnknownError|ActivityInProgress)|workDomainMask)|wlineCharacter|xt(?:StepInterfaceStyle|FunctionKey))|EXTSTEPStringEncoding|a(?:t(?:iveShortGlyphPacking|uralTextAlignment)|rrowFontMask))|C(?:hange(?:ReadOtherContents|GrayCell(?:Mask)?|BackgroundCell(?:Mask)?|Cleared|Done|Undone|Autosaved)|MYK(?:ModeColorPanel|ColorSpaceModel)|ircular(?:BezelStyle|Slider)|o(?:n(?:stantValueExpressionType|t(?:inuousCapacityLevelIndicatorStyle|entsCellMask|ain(?:sComparison|erSpecifierError)|rol(?:Glyph|KeyMask))|densedFontMask)|lor(?:Panel(?:RGBModeMask|GrayModeMask|HSBModeMask|C(?:MYKModeMask|olorListModeMask|ustomPaletteModeMask|rayonModeMask)|WheelModeMask|AllModesMask)|ListModeColorPanel)|reServiceDirectory|m(?:p(?:osite(?:XOR|Source(?:In|O(?:ut|ver)|Atop)|Highlight|C(?:opy|lear)|Destination(?:In|O(?:ut|ver)|Atop)|Plus(?:Darker|Lighter))|ressedFontMask)|mandKeyMask))|u(?:stom(?:SelectorPredicateOperatorType|PaletteModeColorPanel)|r(?:sor(?:Update(?:Mask)?|PointingDevice)|veToBezierPathElement))|e(?:nterT(?:extAlignment|abStopType)|ll(?:State|H(?:ighlighted|as(?:Image(?:Horizontal|OnLeftOrBottom)|OverlappingImage))|ChangesContents|Is(?:Bordered|InsetButton)|Disabled|Editable|LightsBy(?:Gray|Background|Contents)|AllowsMixedState))|l(?:ipPagination|o(?:s(?:ePathBezierPathElement|ableWindowMask)|ckAndCalendarDatePickerStyle)|ear(?:ControlTint|DisplayFunctionKey|LineFunctionKey))|a(?:seInsensitive(?:Search|PredicateOption)|n(?:notCreateScriptCommandError|cel(?:Button|TextMovement))|chesDirectory|lculation(?:NoError|Overflow|DivideByZero|Underflow|LossOfPrecision)|rriageReturnCharacter)|r(?:itical(?:Request|AlertStyle)|ayonModeColorPanel))|T(?:hick(?:SquareBezelStyle|erSquareBezelStyle)|ypesetter(?:Behavior|HorizontalTabAction|ContainerBreakAction|ZeroAdvancementAction|OriginalBehavior|ParagraphBreakAction|WhitespaceAction|L(?:ineBreakAction|atestBehavior))|i(?:ckMark(?:Right|Below|Left|Above)|tledWindowMask|meZoneDatePickerElementFlag)|o(?:olbarItemVisibilityPriority(?:Standard|High|User|Low)|pTabsBezelBorder|ggleButton)|IFF(?:Compression(?:N(?:one|EXT)|CCITTFAX(?:3|4)|OldJPEG|JPEG|PackBits|LZW)|FileType)|e(?:rminate(?:Now|Cancel|Later)|xt(?:Read(?:InapplicableDocumentTypeError|WriteErrorM(?:inimum|aximum))|Block(?:M(?:i(?:nimum(?:Height|Width)|ddleAlignment)|a(?:rgin|ximum(?:Height|Width)))|B(?:o(?:ttomAlignment|rder)|aselineAlignment)|Height|TopAlignment|P(?:ercentageValueType|adding)|Width|AbsoluteValueType)|StorageEdited(?:Characters|Attributes)|CellType|ured(?:RoundedBezelStyle|BackgroundWindowMask|SquareBezelStyle)|Table(?:FixedLayoutAlgorithm|AutomaticLayoutAlgorithm)|Field(?:RoundedBezel|SquareBezel|AndStepperDatePickerStyle)|WriteInapplicableDocumentTypeError|ListPrependEnclosingMarker))|woByteGlyphPacking|ab(?:Character|TextMovement|le(?:tP(?:oint(?:Mask|EventSubtype)?|roximity(?:Mask|EventSubtype)?)|Column(?:NoResizing|UserResizingMask|AutoresizingMask)|View(?:ReverseSequentialColumnAutoresizingStyle|GridNone|S(?:olid(?:HorizontalGridLineMask|VerticalGridLineMask)|equentialColumnAutoresizingStyle)|NoColumnAutoresizing|UniformColumnAutoresizingStyle|FirstColumnOnlyAutoresizingStyle|LastColumnOnlyAutoresizingStyle)))|rackModeMatrix)|I(?:n(?:sert(?:CharFunctionKey|FunctionKey|LineFunctionKey)|t(?:Type|ernalS(?:criptError|pecifierError))|dexSubelement|validIndexSpecifierError|formational(?:Request|AlertStyle)|PredicateOperatorType)|talicFontMask|SO(?:2022JPStringEncoding|Latin(?:1StringEncoding|2StringEncoding))|dentityMappingCharacterCollection|llegalTextMovement|mage(?:R(?:ight|ep(?:MatchesDevice|LoadStatus(?:ReadingHeader|Completed|InvalidData|Un(?:expectedEOF|knownType)|WillNeedAllData)))|Below|C(?:ellType|ache(?:BySize|Never|Default|Always))|Interpolation(?:High|None|Default|Low)|O(?:nly|verlaps)|Frame(?:Gr(?:oove|ayBezel)|Button|None|Photo)|L(?:oadStatus(?:ReadError|C(?:ompleted|ancelled)|InvalidData|UnexpectedEOF)|eft)|A(?:lign(?:Right|Bottom(?:Right|Left)?|Center|Top(?:Right|Left)?|Left)|bove)))|O(?:n(?:State|eByteGlyphPacking|OffButton|lyScrollerArrows)|ther(?:Mouse(?:D(?:own(?:Mask)?|ragged(?:Mask)?)|Up(?:Mask)?)|TextMovement)|SF1OperatingSystem|pe(?:n(?:GL(?:GO(?:Re(?:setLibrary|tainRenderers)|ClearFormatCache|FormatCacheSize)|PFA(?:R(?:obust|endererID)|M(?:inimumPolicy|ulti(?:sample|Screen)|PSafe|aximumPolicy)|BackingStore|S(?:creenMask|te(?:ncilSize|reo)|ingleRenderer|upersample|ample(?:s|Buffers|Alpha))|NoRecovery|C(?:o(?:lor(?:Size|Float)|mpliant)|losestPolicy)|OffScreen|D(?:oubleBuffer|epthSize)|PixelBuffer|VirtualScreenCount|FullScreen|Window|A(?:cc(?:umSize|elerated)|ux(?:Buffers|DepthStencil)|l(?:phaSize|lRenderers))))|StepUnicodeReservedBase)|rationNotSupportedForKeyS(?:criptError|pecifierError))|ffState|KButton|rPredicateType|bjC(?:B(?:itfield|oolType)|S(?:hortType|tr(?:ingType|uctType)|electorType)|NoType|CharType|ObjectType|DoubleType|UnionType|PointerType|VoidType|FloatType|Long(?:Type|longType)|ArrayType))|D(?:i(?:s(?:c(?:losureBezelStyle|reteCapacityLevelIndicatorStyle)|playWindowRunLoopOrdering)|acriticInsensitivePredicateOption|rect(?:Selection|PredicateModifier))|o(?:c(?:ModalWindowMask|ument(?:Directory|ationDirectory))|ubleType|wn(?:TextMovement|ArrowFunctionKey))|e(?:s(?:cendingPageOrder|ktopDirectory)|cimalTabStopType|v(?:ice(?:NColorSpaceModel|IndependentModifierFlagsMask)|eloper(?:Directory|ApplicationDirectory))|fault(?:ControlTint|TokenStyle)|lete(?:Char(?:acter|FunctionKey)|FunctionKey|LineFunctionKey)|moApplicationDirectory)|a(?:yCalendarUnit|teFormatter(?:MediumStyle|Behavior(?:10|Default)|ShortStyle|NoStyle|FullStyle|LongStyle))|ra(?:wer(?:Clos(?:ingState|edState)|Open(?:ingState|State))|gOperation(?:Generic|Move|None|Copy|Delete|Private|Every|Link|All)))|U(?:ser(?:CancelledError|D(?:irectory|omainMask)|FunctionKey)|RL(?:Handle(?:NotLoaded|Load(?:Succeeded|InProgress|Failed))|CredentialPersistence(?:None|Permanent|ForSession))|n(?:scaledWindowMask|cachedRead|i(?:codeStringEncoding|talicFontMask|fiedTitleAndToolbarWindowMask)|d(?:o(?:CloseGroupingRunLoopOrdering|FunctionKey)|e(?:finedDateComponent|rline(?:Style(?:Single|None|Thick|Double)|Pattern(?:Solid|D(?:ot|ash(?:Dot(?:Dot)?)?)))))|known(?:ColorSpaceModel|P(?:ointingDevice|ageOrder)|KeyS(?:criptError|pecifierError))|boldFontMask)|tilityWindowMask|TF8StringEncoding|p(?:dateWindowsRunLoopOrdering|TextMovement|ArrowFunctionKey))|J(?:ustifiedTextAlignment|PEG(?:2000FileType|FileType)|apaneseEUC(?:GlyphPacking|StringEncoding))|P(?:o(?:s(?:t(?:Now|erFontMask|WhenIdle|ASAP)|iti(?:on(?:Replace|Be(?:fore|ginning)|End|After)|ve(?:IntType|DoubleType|FloatType)))|pUp(?:NoArrow|ArrowAt(?:Bottom|Center))|werOffEventType|rtraitOrientation)|NGFileType|ush(?:InCell(?:Mask)?|OnPushOffButton)|e(?:n(?:TipMask|UpperSideMask|PointingDevice|LowerSideMask)|riodic(?:Mask)?)|P(?:S(?:caleField|tatus(?:Title|Field)|aveButton)|N(?:ote(?:Title|Field)|ame(?:Title|Field))|CopiesField|TitleField|ImageButton|OptionsButton|P(?:a(?:perFeedButton|ge(?:Range(?:To|From)|ChoiceMatrix))|reviewButton)|LayoutButton)|lainTextTokenStyle|a(?:useFunctionKey|ragraphSeparatorCharacter|ge(?:DownFunctionKey|UpFunctionKey))|r(?:int(?:ing(?:ReplyLater|Success|Cancelled|Failure)|ScreenFunctionKey|erTable(?:NotFound|OK|Error)|FunctionKey)|o(?:p(?:ertyList(?:XMLFormat|MutableContainers(?:AndLeaves)?|BinaryFormat|Immutable|OpenStepFormat)|rietaryStringEncoding)|gressIndicator(?:BarStyle|SpinningStyle|Preferred(?:SmallThickness|Thickness|LargeThickness|AquaThickness)))|e(?:ssedTab|vFunctionKey))|L(?:HeightForm|CancelButton|TitleField|ImageButton|O(?:KButton|rientationMatrix)|UnitsButton|PaperNameButton|WidthForm))|E(?:n(?:terCharacter|d(?:sWith(?:Comparison|PredicateOperatorType)|FunctionKey))|v(?:e(?:nOddWindingRule|rySubelement)|aluatedObjectExpressionType)|qualTo(?:Comparison|PredicateOperatorType)|ra(?:serPointingDevice|CalendarUnit|DatePickerElementFlag)|x(?:clude(?:10|QuickDrawElementsIconCreationOption)|pandedFontMask|ecuteFunctionKey))|V(?:i(?:ew(?:M(?:in(?:XMargin|YMargin)|ax(?:XMargin|YMargin))|HeightSizable|NotSizable|WidthSizable)|aPanelFontAction)|erticalRuler|a(?:lidationErrorM(?:inimum|aximum)|riableExpressionType))|Key(?:SpecifierEvaluationScriptError|Down(?:Mask)?|Up(?:Mask)?|PathExpressionType|Value(?:MinusSetMutation|SetSetMutation|Change(?:Re(?:placement|moval)|Setting|Insertion)|IntersectSetMutation|ObservingOption(?:New|Old)|UnionSetMutation|ValidationError))|QTMovie(?:NormalPlayback|Looping(?:BackAndForthPlayback|Playback))|F(?:1(?:1FunctionKey|7FunctionKey|2FunctionKey|8FunctionKey|3FunctionKey|9FunctionKey|4FunctionKey|5FunctionKey|FunctionKey|0FunctionKey|6FunctionKey)|7FunctionKey|i(?:nd(?:PanelAction(?:Replace(?:A(?:ndFind|ll(?:InSelection)?))?|S(?:howFindPanel|e(?:tFindString|lectAll(?:InSelection)?))|Next|Previous)|FunctionKey)|tPagination|le(?:Read(?:No(?:SuchFileError|PermissionError)|CorruptFileError|In(?:validFileNameError|applicableStringEncodingError)|Un(?:supportedSchemeError|knownError))|HandlingPanel(?:CancelButton|OKButton)|NoSuchFileError|ErrorM(?:inimum|aximum)|Write(?:NoPermissionError|In(?:validFileNameError|applicableStringEncodingError)|OutOfSpaceError|Un(?:supportedSchemeError|knownError))|LockingError)|xedPitchFontMask)|2(?:1FunctionKey|7FunctionKey|2FunctionKey|8FunctionKey|3FunctionKey|9FunctionKey|4FunctionKey|5FunctionKey|FunctionKey|0FunctionKey|6FunctionKey)|o(?:nt(?:Mo(?:noSpaceTrait|dernSerifsClass)|BoldTrait|S(?:ymbolicClass|criptsClass|labSerifsClass|ansSerifClass)|C(?:o(?:ndensedTrait|llectionApplicationOnlyMask)|larendonSerifsClass)|TransitionalSerifsClass|I(?:ntegerAdvancementsRenderingMode|talicTrait)|O(?:ldStyleSerifsClass|rnamentalsClass)|DefaultRenderingMode|U(?:nknownClass|IOptimizedTrait)|Panel(?:S(?:hadowEffectModeMask|t(?:andardModesMask|rikethroughEffectModeMask)|izeModeMask)|CollectionModeMask|TextColorEffectModeMask|DocumentColorEffectModeMask|UnderlineEffectModeMask|FaceModeMask|All(?:ModesMask|EffectsModeMask))|ExpandedTrait|VerticalTrait|F(?:amilyClassMask|reeformSerifsClass)|Antialiased(?:RenderingMode|IntegerAdvancementsRenderingMode))|cusRing(?:Below|Type(?:None|Default|Exterior)|Only|Above)|urByteGlyphPacking|rm(?:attingError(?:M(?:inimum|aximum))?|FeedCharacter))|8FunctionKey|unction(?:ExpressionType|KeyMask)|3(?:1FunctionKey|2FunctionKey|3FunctionKey|4FunctionKey|5FunctionKey|FunctionKey|0FunctionKey)|9FunctionKey|4FunctionKey|P(?:RevertButton|S(?:ize(?:Title|Field)|etButton)|CurrentField|Preview(?:Button|Field))|l(?:oat(?:ingPointSamplesBitmapFormat|Type)|agsChanged(?:Mask)?)|axButton|5FunctionKey|6FunctionKey)|W(?:heelModeColorPanel|indow(?:s(?:NTOperatingSystem|CP125(?:1StringEncoding|2StringEncoding|3StringEncoding|4StringEncoding|0StringEncoding)|95(?:InterfaceStyle|OperatingSystem))|M(?:iniaturizeButton|ovedEventType)|Below|CloseButton|ToolbarButton|ZoomButton|Out|DocumentIconButton|ExposedEventType|Above)|orkspaceLaunch(?:NewInstance|InhibitingBackgroundOnly|Default|PreferringClassic|WithoutA(?:ctivation|ddingToRecents)|A(?:sync|nd(?:Hide(?:Others)?|Print)|llowingClassicStartup))|eek(?:day(?:CalendarUnit|OrdinalCalendarUnit)|CalendarUnit)|a(?:ntsBidiLevels|rningAlertStyle)|r(?:itingDirection(?:RightToLeft|Natural|LeftToRight)|apCalendarComponents))|L(?:i(?:stModeMatrix|ne(?:Moves(?:Right|Down|Up|Left)|B(?:order|reakBy(?:C(?:harWrapping|lipping)|Truncating(?:Middle|Head|Tail)|WordWrapping))|S(?:eparatorCharacter|weep(?:Right|Down|Up|Left))|ToBezierPathElement|DoesntMove|arSlider)|teralSearch|kePredicateOperatorType|ghterFontAction|braryDirectory)|ocalDomainMask|e(?:ssThan(?:Comparison|OrEqualTo(?:Comparison|PredicateOperatorType)|PredicateOperatorType)|ft(?:Mouse(?:D(?:own(?:Mask)?|ragged(?:Mask)?)|Up(?:Mask)?)|T(?:ext(?:Movement|Alignment)|ab(?:sBezelBorder|StopType))|ArrowFunctionKey))|a(?:yout(?:RightToLeft|NotDone|CantFit|OutOfGlyphs|Done|LeftToRight)|ndscapeOrientation)|ABColorSpaceModel)|A(?:sc(?:iiWithDoubleByteEUCGlyphPacking|endingPageOrder)|n(?:y(?:Type|PredicateModifier|EventMask)|choredSearch|imation(?:Blocking|Nonblocking(?:Threaded)?|E(?:ffect(?:DisappearingItemDefault|Poof)|ase(?:In(?:Out)?|Out))|Linear)|dPredicateType)|t(?:Bottom|tachmentCharacter|omicWrite|Top)|SCIIStringEncoding|d(?:obe(?:GB1CharacterCollection|CNS1CharacterCollection|Japan(?:1CharacterCollection|2CharacterCollection)|Korea1CharacterCollection)|dTraitFontAction|minApplicationDirectory)|uto(?:saveOperation|Pagination)|pp(?:lication(?:SupportDirectory|D(?:irectory|e(?:fined(?:Mask)?|legateReply(?:Success|Cancel|Failure)|activatedEventType))|ActivatedEventType)|KitDefined(?:Mask)?)|l(?:ternateKeyMask|pha(?:ShiftKeyMask|NonpremultipliedBitmapFormat|FirstBitmapFormat)|ert(?:SecondButtonReturn|ThirdButtonReturn|OtherReturn|DefaultReturn|ErrorReturn|FirstButtonReturn|AlternateReturn)|l(?:ScrollerParts|DomainsMask|PredicateModifier|LibrariesDirectory|ApplicationsDirectory))|rgument(?:sWrongScriptError|EvaluationScriptError)|bove(?:Bottom|Top)|WTEventType)))(?:\\b)" - }, - { - token: "support.function.C99.c", - regex: C_Highlight_File.cFunctions - }, - { - token : cObj.getKeywords(), - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, - { - token: "punctuation.section.scope.begin.objc", - regex: "\\[", - next: "bracketed_content" - }, - { - token: "meta.function.objc", - regex: "^(?:-|\\+)\\s*" - } - ], - "constant_NSString": [ - { - token: "constant.character.escape.objc", - regex: escapedConstRe - }, - { - token: "invalid.illegal.unknown-escape.objc", - regex: "\\\\." - }, - { - token: "string", - regex: '[^"\\\\]+' - }, - { - token: "punctuation.definition.string.end", - regex: "\"", - next: "start" - } - ], - "protocol_list": [ - { - token: "punctuation.section.scope.end.objc", - regex: ">", - next: "start" - }, - { - token: "support.other.protocol.objc", - 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" - } - ], - "selectors": [ - { - token: "support.function.any-method.name-of-parameter.objc", - regex: "\\b(?:[a-zA-Z_:][\\w]*)+" - }, - { - token: "punctuation", - regex: "\\)", - next: "start" - } - ], - "bracketed_content": [ - { - token: "punctuation.section.scope.end.objc", - regex: "]", - next: "start" - }, - { - token: ["support.function.any-method.objc"], - regex: "(?:predicateWithFormat:| NSPredicate predicateWithFormat:)", - next: "start" - }, - { - token: "support.function.any-method.objc", - regex: "\\w+(?::|(?=]))", - next: "start" - } - ], - "bracketed_strings": [ - { - token: "punctuation.section.scope.end.objc", - regex: "]", - next: "start" - }, - { - token: "keyword.operator.logical.predicate.cocoa", - regex: "\\b(?:AND|OR|NOT|IN)\\b" - }, - { - token: ["invalid.illegal.unknown-method.objc", "punctuation.separator.arguments.objc"], - regex: "\\b(\\w+)(:)" - }, - { - regex: "\\b(?:ALL|ANY|SOME|NONE)\\b", - token: "constant.language.predicate.cocoa" - }, - { - regex: "\\b(?:NULL|NIL|SELF|TRUE|YES|FALSE|NO|FIRST|LAST|SIZE)\\b", - token: "constant.language.predicate.cocoa" - }, - { - regex: "\\b(?:MATCHES|CONTAINS|BEGINSWITH|ENDSWITH|BETWEEN)\\b", - token: "keyword.operator.comparison.predicate.cocoa" - }, - { - regex: "\\bC(?:ASEINSENSITIVE|I)\\b", - token: "keyword.other.modifier.predicate.cocoa" - }, - { - regex: "\\b(?:ANYKEY|SUBQUERY|CAST|TRUEPREDICATE|FALSEPREDICATE)\\b", - token: "keyword.other.predicate.cocoa" - }, - { - regex: escapedConstRe, - token: "constant.character.escape.objc" - }, - { - regex: "\\\\.", - token: "invalid.illegal.unknown-escape.objc" - }, - { - token: "string", - regex: '[^"\\\\]' - }, - { - token: "punctuation.definition.string.end.objc", - regex: "\"", - next: "predicates" - } - ], - "comment" : [ - { - token : "comment", // closing comment - regex : ".*?\\*\\/", - next : "start" - }, { - defaultToken : "comment" - } - ], - "methods" : [ - { - token : "meta.function.objc", - regex : "(?=\\{|#)|;", - next : "start" - } - ] -}; - - // copy in C-Rules directly - for (var r in cRules) { - if (this.$rules[r]) { - if (this.$rules[r].push) - this.$rules[r].push.apply(this.$rules[r], cRules[r]); - } else { - this.$rules[r] = cRules[r]; - } - } - - this.$rules.bracketed_content = this.$rules.bracketed_content.concat( - this.$rules.start, specialVariables - ); - - this.embedRules(DocCommentHighlightRules, "doc-", - [ DocCommentHighlightRules.getEndRule("start") ]); -}; - -oop.inherits(ObjectiveCHighlightRules, CHighlightRules); - -exports.ObjectiveCHighlightRules = ObjectiveCHighlightRules; -}); diff --git a/lib/ace/mode/ocaml.js b/lib/ace/mode/ocaml.js deleted file mode 100644 index ff7825b0810..00000000000 --- a/lib/ace/mode/ocaml.js +++ /dev/null @@ -1,98 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var OcamlHighlightRules = require("./ocaml_highlight_rules").OcamlHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; - -var Mode = function() { - this.HighlightRules = OcamlHighlightRules; - this.$behaviour = this.$defaultBehaviour; - - this.$outdent = new MatchingBraceOutdent(); -}; -oop.inherits(Mode, TextMode); - -var indenter = /(?:[({[=:]|[-=]>|\b(?:else|try|with))\s*$/; - -(function() { - - this.toggleCommentLines = function(state, doc, startRow, endRow) { - var i, line; - var outdent = true; - var re = /^\s*\(\*(.*)\*\)/; - - for (i=startRow; i<= endRow; i++) { - if (!re.test(doc.getLine(i))) { - outdent = false; - break; - } - } - - var range = new Range(0, 0, 0, 0); - for (i=startRow; i<= endRow; i++) { - line = doc.getLine(i); - range.start.row = i; - range.end.row = i; - range.end.column = line.length; - - doc.replace(range, outdent ? line.match(re)[1] : "(*" + line + "*)"); - } - }; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - var tokens = this.getTokenizer().getLineTokens(line, state).tokens; - - if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') && - state === 'start' && indenter.test(line)) - indent += tab; - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/ocaml"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); - diff --git a/lib/ace/mode/pascal.js b/lib/ace/mode/pascal.js deleted file mode 100644 index 7958ce63294..00000000000 --- a/lib/ace/mode/pascal.js +++ /dev/null @@ -1,68 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributor(s): - * - * - * - * ***** END LICENSE BLOCK ***** */ - -/* - THIS FILE WAS AUTOGENERATED BY mode.tmpl.js -*/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var PascalHighlightRules = require("./pascal_highlight_rules").PascalHighlightRules; -// TODO: pick appropriate fold mode -var FoldMode = require("./folding/coffee").FoldMode; - -var Mode = function() { - this.HighlightRules = PascalHighlightRules; - this.foldingRules = new FoldMode(); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = ["--", "//"]; - this.blockComment = [ - {start: "(*", end: "*)"}, - {start: "{", end: "}"} - ]; - - this.$id = "ace/mode/pascal"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); \ No newline at end of file diff --git a/lib/ace/mode/pascal_highlight_rules.js b/lib/ace/mode/pascal_highlight_rules.js deleted file mode 100644 index a617da7709f..00000000000 --- a/lib/ace/mode/pascal_highlight_rules.js +++ /dev/null @@ -1,127 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2012, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -/* THIS FILE WAS AUTOGENERATED FROM tool\tm bundles\pascal.tmbundle\Syntaxes\Pascal.plist (UUID: F42FA544-6B1C-11D9-9517-000D93589AF6) */ -/**************************************************************** - * IT MIGHT NOT BE PERFECT, PARTICULARLY: * - * IN DECIDING STATES TO TRANSITION TO, * - * IGNORING WHITESPACE, * - * IGNORING GROUPS WITH ?:, * - * EXTENDING EXISTING MODES, * - * GATHERING KEYWORDS, OR * - * DECIDING WHEN TO USE PUSH. * - * ...But it's a good start from an existing *.tmlanguage file. * - ****************************************************************/ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var PascalHighlightRules = function() { - // regexp must not have capturing parentheses. Use (?:) instead. - // regexps are ordered -> the first match is used - - this.$rules = { start: - [ { caseInsensitive: true, - token: 'keyword.control.pascal', - regex: '\\b(?:(absolute|abstract|all|and|and_then|array|as|asm|attribute|begin|bindable|case|class|const|constructor|destructor|div|do|do|else|end|except|export|exports|external|far|file|finalization|finally|for|forward|goto|if|implementation|import|in|inherited|initialization|interface|interrupt|is|label|library|mod|module|name|near|nil|not|object|of|only|operator|or|or_else|otherwise|packed|pow|private|program|property|protected|public|published|qualified|record|repeat|resident|restricted|segment|set|shl|shr|then|to|try|type|unit|until|uses|value|var|view|virtual|while|with|xor))\\b' }, - { caseInsensitive: true, - token: - [ 'variable.pascal', "text", - 'storage.type.prototype.pascal', - 'entity.name.function.prototype.pascal' ], - regex: '\\b(function|procedure)(\\s+)(\\w+)(\\.\\w+)?(?=(?:\\(.*?\\))?;\\s*(?:attribute|forward|external))' }, - { caseInsensitive: true, - token: - [ 'variable.pascal', "text", - 'storage.type.function.pascal', - 'entity.name.function.pascal' ], - regex: '\\b(function|procedure)(\\s+)(\\w+)(\\.\\w+)?' }, - { token: 'constant.numeric.pascal', - 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' }, - { token: 'punctuation.definition.comment.pascal', - regex: '--.*$', - push_: - [ { token: 'comment.line.double-dash.pascal.one', - regex: '$', - next: 'pop' }, - { defaultToken: 'comment.line.double-dash.pascal.one' } ] }, - { token: 'punctuation.definition.comment.pascal', - regex: '//.*$', - push_: - [ { token: 'comment.line.double-slash.pascal.two', - regex: '$', - next: 'pop' }, - { defaultToken: 'comment.line.double-slash.pascal.two' } ] }, - { token: 'punctuation.definition.comment.pascal', - regex: '\\(\\*', - push: - [ { token: 'punctuation.definition.comment.pascal', - regex: '\\*\\)', - next: 'pop' }, - { defaultToken: 'comment.block.pascal.one' } ] }, - { token: 'punctuation.definition.comment.pascal', - regex: '\\{', - push: - [ { token: 'punctuation.definition.comment.pascal', - regex: '\\}', - next: 'pop' }, - { defaultToken: 'comment.block.pascal.two' } ] }, - { token: 'punctuation.definition.string.begin.pascal', - regex: '"', - push: - [ { token: 'constant.character.escape.pascal', regex: '\\\\.' }, - { token: 'punctuation.definition.string.end.pascal', - regex: '"', - next: 'pop' }, - { defaultToken: 'string.quoted.double.pascal' } ] - //Double quoted strings are an extension and (generally) support C-style escape sequences. - }, - { token: 'punctuation.definition.string.begin.pascal', - regex: '\'', - push: - [ { token: 'constant.character.escape.apostrophe.pascal', - regex: '\'\'' }, - { token: 'punctuation.definition.string.end.pascal', - regex: '\'', - next: 'pop' }, - { defaultToken: 'string.quoted.single.pascal' } ] }, - { token: 'keyword.operator', - regex: '[+\\-;,/*%]|:=|=' } ] }; - - this.normalizeRules(); -}; - -oop.inherits(PascalHighlightRules, TextHighlightRules); - -exports.PascalHighlightRules = PascalHighlightRules; -}); \ No newline at end of file diff --git a/lib/ace/mode/perl.js b/lib/ace/mode/perl.js deleted file mode 100644 index 01778a7cf49..00000000000 --- a/lib/ace/mode/perl.js +++ /dev/null @@ -1,90 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var PerlHighlightRules = require("./perl_highlight_rules").PerlHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = PerlHighlightRules; - - this.$outdent = new MatchingBraceOutdent(); - this.foldingRules = new CStyleFoldMode({start: "^=(begin|item)\\b", end: "^=(cut)\\b"}); - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - - this.lineCommentStart = "#"; - this.blockComment = [ - {start: "=begin", end: "=cut", lineStartOnly: true}, - {start: "=item", end: "=cut", lineStartOnly: true} - ]; - - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[:]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.$id = "ace/mode/perl"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/pgsql.js b/lib/ace/mode/pgsql.js deleted file mode 100755 index 68693db0308..00000000000 --- a/lib/ace/mode/pgsql.js +++ /dev/null @@ -1,59 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var oop = require("../lib/oop"); -var TextMode = require("../mode/text").Mode; -var PgsqlHighlightRules = require("./pgsql_highlight_rules").PgsqlHighlightRules; - -var Mode = function() { - this.HighlightRules = PgsqlHighlightRules; - this.$behaviour = this.$defaultBehaviour; -}; -oop.inherits(Mode, TextMode); - -(function() { - this.lineCommentStart = "--"; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - if (state == "start" || state == "keyword.statementEnd") { - return ""; - } else { - return this.$getIndent(line); // Keep whatever indent the previous line has - } - }; - - this.$id = "ace/mode/pgsql"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/php.js b/lib/ace/mode/php.js deleted file mode 100644 index 48f70eb6975..00000000000 --- a/lib/ace/mode/php.js +++ /dev/null @@ -1,155 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var PhpHighlightRules = require("./php_highlight_rules").PhpHighlightRules; -var PhpLangHighlightRules = require("./php_highlight_rules").PhpLangHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; -var WorkerClient = require("../worker/worker_client").WorkerClient; -var PhpCompletions = require("./php_completions").PhpCompletions; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; -var unicode = require("../unicode"); -var HtmlMode = require("./html").Mode; -var JavaScriptMode = require("./javascript").Mode; -var CssMode = require("./css").Mode; - -var PhpMode = function(opts) { - this.HighlightRules = PhpLangHighlightRules; - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.$completer = new PhpCompletions(); - this.foldingRules = new CStyleFoldMode(); -}; -oop.inherits(PhpMode, TextMode); - -(function() { - - this.tokenRe = new RegExp("^[" + unicode.wordChars + "_]+", "g"); - this.nonTokenRe = new RegExp("^(?:[^" + unicode.wordChars + "_]|\\s])+", "g"); - - this.lineCommentStart = ["//", "#"]; - this.blockComment = {start: "/*", end: "*/"}; - - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[:]\s*$/); - if (match) { - indent += tab; - } - } else if (state == "doc-start") { - if (endState != "doc-start") { - return ""; - } - var match = line.match(/^\s*(\/?)\*/); - if (match) { - if (match[1]) { - indent += " "; - } - indent += "* "; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.getCompletions = function(state, session, pos, prefix) { - return this.$completer.getCompletions(state, session, pos, prefix); - }; - - this.$id = "ace/mode/php-inline"; -}).call(PhpMode.prototype); - -var Mode = function(opts) { - if (opts && opts.inline) { - var mode = new PhpMode(); - mode.createWorker = this.createWorker; - mode.inlinePhp = true; - return mode; - } - HtmlMode.call(this); - this.HighlightRules = PhpHighlightRules; - this.createModeDelegates({ - "js-": JavaScriptMode, - "css-": CssMode, - "php-": PhpMode - }); - this.foldingRules.subModes["php-"] = new CStyleFoldMode(); -}; -oop.inherits(Mode, HtmlMode); - -(function() { - - this.createWorker = function(session) { - var worker = new WorkerClient(["ace"], "ace/mode/php_worker", "PhpWorker"); - worker.attachToDocument(session.getDocument()); - - if (this.inlinePhp) - worker.call("setOptions", [{inline: true}]); - - worker.on("annotate", function(e) { - session.setAnnotations(e.data); - }); - - worker.on("terminate", function() { - session.clearAnnotations(); - }); - - return worker; - }; - - this.$id = "ace/mode/php"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); diff --git a/lib/ace/mode/php/php.js b/lib/ace/mode/php/php.js index 4836b42b960..cf0b56c42a8 100644 --- a/lib/ace/mode/php/php.js +++ b/lib/ace/mode/php/php.js @@ -16,2260 +16,2517 @@ */ - -define(function(require, exports, module) { - -var PHP = {Constants:{}}; - -PHP.Constants.T_INCLUDE = 257; -PHP.Constants.T_INCLUDE_ONCE = 258; -PHP.Constants.T_EVAL = 259; -PHP.Constants.T_REQUIRE = 260; -PHP.Constants.T_REQUIRE_ONCE = 261; -PHP.Constants.T_LOGICAL_OR = 262; -PHP.Constants.T_LOGICAL_XOR = 263; -PHP.Constants.T_LOGICAL_AND = 264; -PHP.Constants.T_PRINT = 265; -PHP.Constants.T_YIELD = 266; -PHP.Constants.T_DOUBLE_ARROW = 267; -PHP.Constants.T_YIELD_FROM = 268; -PHP.Constants.T_PLUS_EQUAL = 269; -PHP.Constants.T_MINUS_EQUAL = 270; -PHP.Constants.T_MUL_EQUAL = 271; -PHP.Constants.T_DIV_EQUAL = 272; -PHP.Constants.T_CONCAT_EQUAL = 273; -PHP.Constants.T_MOD_EQUAL = 274; -PHP.Constants.T_AND_EQUAL = 275; -PHP.Constants.T_OR_EQUAL = 276; -PHP.Constants.T_XOR_EQUAL = 277; -PHP.Constants.T_SL_EQUAL = 278; -PHP.Constants.T_SR_EQUAL = 279; -PHP.Constants.T_POW_EQUAL = 280; -PHP.Constants.T_COALESCE = 281; -PHP.Constants.T_BOOLEAN_OR = 282; -PHP.Constants.T_BOOLEAN_AND = 283; -PHP.Constants.T_IS_EQUAL = 284; -PHP.Constants.T_IS_NOT_EQUAL = 285; -PHP.Constants.T_IS_IDENTICAL = 286; -PHP.Constants.T_IS_NOT_IDENTICAL = 287; -PHP.Constants.T_SPACESHIP = 288; -PHP.Constants.T_IS_SMALLER_OR_EQUAL = 289; -PHP.Constants.T_IS_GREATER_OR_EQUAL = 290; -PHP.Constants.T_SL = 291; -PHP.Constants.T_SR = 292; -PHP.Constants.T_INSTANCEOF = 293; -PHP.Constants.T_INC = 294; -PHP.Constants.T_DEC = 295; -PHP.Constants.T_INT_CAST = 296; -PHP.Constants.T_DOUBLE_CAST = 297; -PHP.Constants.T_STRING_CAST = 298; -PHP.Constants.T_ARRAY_CAST = 299; -PHP.Constants.T_OBJECT_CAST = 300; -PHP.Constants.T_BOOL_CAST = 301; -PHP.Constants.T_UNSET_CAST = 302; -PHP.Constants.T_POW = 303; -PHP.Constants.T_NEW = 304; -PHP.Constants.T_CLONE = 305; -PHP.Constants.T_EXIT = 306; -PHP.Constants.T_IF = 307; -PHP.Constants.T_ELSEIF = 308; -PHP.Constants.T_ELSE = 309; -PHP.Constants.T_ENDIF = 310; -PHP.Constants.T_LNUMBER = 311; -PHP.Constants.T_DNUMBER = 312; -PHP.Constants.T_STRING = 313; -PHP.Constants.T_STRING_VARNAME = 314; -PHP.Constants.T_VARIABLE = 315; -PHP.Constants.T_NUM_STRING = 316; -PHP.Constants.T_INLINE_HTML = 317; -PHP.Constants.T_CHARACTER = 318; -PHP.Constants.T_BAD_CHARACTER = 319; -PHP.Constants.T_ENCAPSED_AND_WHITESPACE = 320; -PHP.Constants.T_CONSTANT_ENCAPSED_STRING = 321; -PHP.Constants.T_ECHO = 322; -PHP.Constants.T_DO = 323; -PHP.Constants.T_WHILE = 324; -PHP.Constants.T_ENDWHILE = 325; -PHP.Constants.T_FOR = 326; -PHP.Constants.T_ENDFOR = 327; -PHP.Constants.T_FOREACH = 328; -PHP.Constants.T_ENDFOREACH = 329; -PHP.Constants.T_DECLARE = 330; -PHP.Constants.T_ENDDECLARE = 331; -PHP.Constants.T_AS = 332; -PHP.Constants.T_SWITCH = 333; -PHP.Constants.T_ENDSWITCH = 334; -PHP.Constants.T_CASE = 335; -PHP.Constants.T_DEFAULT = 336; -PHP.Constants.T_BREAK = 337; -PHP.Constants.T_CONTINUE = 338; -PHP.Constants.T_GOTO = 339; -PHP.Constants.T_FUNCTION = 340; -PHP.Constants.T_CONST = 341; -PHP.Constants.T_RETURN = 342; -PHP.Constants.T_TRY = 343; -PHP.Constants.T_CATCH = 344; -PHP.Constants.T_FINALLY = 345; -PHP.Constants.T_THROW = 346; -PHP.Constants.T_USE = 347; -PHP.Constants.T_INSTEADOF = 348; -PHP.Constants.T_GLOBAL = 349; -PHP.Constants.T_STATIC = 350; -PHP.Constants.T_ABSTRACT = 351; -PHP.Constants.T_FINAL = 352; -PHP.Constants.T_PRIVATE = 353; -PHP.Constants.T_PROTECTED = 354; -PHP.Constants.T_PUBLIC = 355; -PHP.Constants.T_VAR = 356; -PHP.Constants.T_UNSET = 357; -PHP.Constants.T_ISSET = 358; -PHP.Constants.T_EMPTY = 359; -PHP.Constants.T_HALT_COMPILER = 360; -PHP.Constants.T_CLASS = 361; -PHP.Constants.T_TRAIT = 362; -PHP.Constants.T_INTERFACE = 363; -PHP.Constants.T_EXTENDS = 364; -PHP.Constants.T_IMPLEMENTS = 365; -PHP.Constants.T_OBJECT_OPERATOR = 366; -PHP.Constants.T_LIST = 367; -PHP.Constants.T_ARRAY = 368; -PHP.Constants.T_CALLABLE = 369; -PHP.Constants.T_CLASS_C = 370; -PHP.Constants.T_TRAIT_C = 371; -PHP.Constants.T_METHOD_C = 372; -PHP.Constants.T_FUNC_C = 373; -PHP.Constants.T_LINE = 374; -PHP.Constants.T_FILE = 375; -PHP.Constants.T_COMMENT = 376; -PHP.Constants.T_DOC_COMMENT = 377; -PHP.Constants.T_OPEN_TAG = 378; -PHP.Constants.T_OPEN_TAG_WITH_ECHO = 379; -PHP.Constants.T_CLOSE_TAG = 380; -PHP.Constants.T_WHITESPACE = 381; -PHP.Constants.T_START_HEREDOC = 382; -PHP.Constants.T_END_HEREDOC = 383; -PHP.Constants.T_DOLLAR_OPEN_CURLY_BRACES = 384; -PHP.Constants.T_CURLY_OPEN = 385; -PHP.Constants.T_PAAMAYIM_NEKUDOTAYIM = 386; -PHP.Constants.T_NAMESPACE = 387; -PHP.Constants.T_NS_C = 388; -PHP.Constants.T_DIR = 389; -PHP.Constants.T_NS_SEPARATOR = 390; -PHP.Constants.T_ELLIPSIS = 391; - -PHP.Lexer = function(src, ini) { - var heredoc, heredocEndAllowed, - - stateStack = ['INITIAL'], stackPos = 0, - swapState = function(state) { - stateStack[stackPos] = state; - }, - pushState = function(state) { - stateStack[++stackPos] = state; - }, - popState = function() { - --stackPos; - }, - - shortOpenTag = ini === undefined || /^(on|true|1)$/i.test(ini.short_open_tag), - openTag = shortOpenTag - ? /^(\<\?php(?:\r\n|[ \t\r\n])|<\?|\ -snippet scriptsrc - -snippet newscript - -snippet newscriptsrc - -snippet section -
      - ${1} -
      -snippet section. -
      - ${2} -
      -snippet section# -
      - ${2} -
      -snippet select - -snippet select. - -snippet small - ${1} -snippet source - -snippet span - ${1} -snippet strong - ${1} -snippet style - -snippet sub - ${1} -snippet summary - - ${1} - -snippet sup - ${1} -snippet table - - ${2} -
      -snippet table. - - ${3} -
      -snippet table# - - ${3} -
      -snippet tbody - - ${1} - -snippet td - ${1} -snippet td. - ${2} -snippet td# - ${2} -snippet td+ - ${1} - td+${2} -snippet textarea - ${6} -snippet tfoot - - ${1} - -snippet th - ${1} -snippet th. - ${2} -snippet th# - ${2} -snippet th+ - ${1} - th+${2} -snippet thead - - ${1} - -snippet time -