diff --git a/.gitignore b/.gitignore
index 59ec847b..74035e60 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,21 +2,22 @@
.DS_Store
*.swp
*.tmp
-*~
# Project files that should not be in the repo
-.*
-\#*
-!/.gitignore
+.project
+.settings/
+.settings.xml
+.c9settings.xml
+.settings.xml.old
.*.gz
-*.tmTheme.js
# A handy place to put stuff that git should ignore:
/ignore/
-node_modules/
-jam/
-* *
+support/async/
+support/jsdom/
+support/node-htmlparser/
+support/node-o3-xml/
+support/requirejs/
-.git-ref
-npm-debug.log
-deps/
+/node_modules
+support/node-o3-xml-v4/
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index 07bbe371..29473c2b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
+[submodule "support/dryice"]
+ path = support/dryice
+ url = git://github.com/ajaxorg/dryice.git
[submodule "doc/wiki"]
path = doc/wiki
- url = https://github.com/ajaxorg/ace.wiki.git
-[submodule "build"]
- path = build
- url = https://github.com/ajaxorg/ace-builds.git
+ url = git://github.com/ajaxorg/ace.wiki.git
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d2f32091..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1 +0,0 @@
-language: node_js
\ No newline at end of file
diff --git a/CNAME b/CNAME
deleted file mode 100644
index 75431b15..00000000
--- a/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-ace.c9.io
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 062af59c..00000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,15 +0,0 @@
-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.
-
-Happy coding, Cloud9
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 3077d171..76b2313b 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,229 +1,3 @@
-Version 1.2.0-pre
-
-* New Features
- - Indented soft wrap (danyaPostfactum)
-
-* 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
-
-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)
@@ -253,14 +27,15 @@ Version 1.2.0-pre
- SCAD (Jacob Hansson)
* Live syntax checks
- - Lint for CSS using CSS Lint
+ - 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)
+ - Solarized dark/light (David Alan
+ Hjelle)
- Vibrant Ink (Michael Schwartz)
* Small Features/Enhancements
@@ -273,8 +48,10 @@ Version 1.2.0-pre
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)
+ - 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
@@ -282,7 +59,8 @@ Version 1.2.0-pre
- 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)
+ - Make keyboard infrastructure route keys like []^$ the right way (Julian
+ Viereck)
2011.02.14, Version 0.1.6
@@ -335,4 +113,4 @@ Version 1.2.0-pre
* 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
+* Changing a document added a new empty line at the end
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 4760be2a..853e4fd5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,24 +1,476 @@
-Copyright (c) 2010, Ajax.org B.V.
-All rights reserved.
+Licensed under the tri-license MPL/LGPL/GPL.
-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.
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
-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.
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (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.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
+
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 29cf0495..33e1d4e2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,34 +1,13 @@
-.PHONY : doc build clean dist
-
-pre_build:
- git rev-parse HEAD > .git-ref
+build:
mkdir -p build/src
- mkdir -p build/demo/kitchen-sink
+ mkdir -p build/demo
mkdir -p build/textarea/src
- cp -r demo/kitchen-sink/styles.css build/demo/kitchen-sink/styles.css
- cp demo/kitchen-sink/logo.png build/demo/kitchen-sink/logo.png
- cp -r doc/site/images build/textarea
-
-build: pre_build
+ cp demo/styles.css build/demo/styles.css
+ cp demo/logo.png build/demo/logo.png
+
./Makefile.dryice.js normal
- ./Makefile.dryice.js demo
-
-# Minimal build: call Makefile.dryice.js only if our sources changed
-basic: build/src/ace.js
-
-build/src/ace.js : ${wildcard lib/*} \
- ${wildcard lib/*/*} \
- ${wildcard lib/*/*/*} \
- ${wildcard lib/*/*/*/*} \
- ${wildcard lib/*/*/*/*/*} \
- ${wildcard lib/*/*/*/*/*/*}
- ./Makefile.dryice.js
-
-doc:
- cd doc;\
- (test -d node_modules && npm update) || npm install;\
- node build.js
+ ./Makefile.dryice.js bm
clean:
rm -rf build
diff --git a/Makefile.dryice.js b/Makefile.dryice.js
index 0ce7c657..f828a449 100755
--- a/Makefile.dryice.js
+++ b/Makefile.dryice.js
@@ -1,571 +1,367 @@
#!/usr/bin/env node
/* ***** BEGIN LICENSE BLOCK *****
- * Distributed under the BSD license:
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
- * Copyright (c) 2010, Ajax.org B.V.
- * All rights reserved.
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
*
- * 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.
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
*
- * 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.
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Julian Viereck
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
-var fs = require("fs");
-var path = require("path");
-var copy = require('architect-build/copy');
-var build = require('architect-build/build');
-
-var ACE_HOME = __dirname;
-var BUILD_DIR = ACE_HOME + "/build";
-var CACHE = {};
-
-function main(args) {
- if (args.indexOf("updateModes") !== -1) {
- return updateModes();
+var args = process.argv;
+var target = null;
+var targetDir = null;
+if (args.length == 3) {
+ target = args[2];
+ // Check if 'target' contains some allowed value.
+ if (target != "normal" && target != "bm") {
+ target = null;
}
- var type = "minimal";
- args = args.map(function(x) {
- if (x[0] == "-" && x[1] != "-")
- return "-" + x;
- return x;
- }).filter(Boolean);
+}
- if (args[2] && (args[2][0] != "-" || args[2].indexOf("h") != -1))
- type = args[2];
+if (!target) {
+ console.log("--- Ace Dryice Build Tool ---");
+ console.log("");
+ console.log("Options:");
+ console.log(" normal Runs embedded build of Ace");
+ console.log(" bm Runs bookmarklet build of Ace");
+ process.exit(0);
+} else {
+ if (target == "normal") {
+ targetDir = "build";
+ } else {
+ targetDir = "build/textarea";
+ function shadow(input) {
+ if (typeof input !== 'string') {
+ input = input.toString();
+ }
- var i = args.indexOf("--target");
- if (i != -1 && args[i+1])
- BUILD_DIR = args[i+1];
-
- if (args.indexOf("--h") == -1) {
- if (type == "minimal") {
- buildAce({
- compress: args.indexOf("--m") != -1,
- noconflict: args.indexOf("--nc") != -1,
- shrinkwrap: args.indexOf("--s") != -1
- });
- } else if (type == "normal") {
- ace();
- } else if (type == "demo") {
- demo();
- } else if (type == "full") {
- ace();
- demo();
- } else if (type == "highlighter") {
- // TODO
+ return input.replace(/define\(/g, "__ace_shadowed__.define(");
}
}
}
-function showHelp(type) {
- console.log("--- Ace Dryice Build Tool ---");
- console.log("");
- console.log("Options:");
- console.log(" minimal Places necessary Ace files out in build dir; uses configuration flags below [default]");
- console.log(" normal Runs four Ace builds--minimal, minimal-noconflict, minimal-min, and minimal-noconflict-min");
- console.log(" demo Runs demo build of Ace");
- console.log(" full all of above");
- console.log(" highlighter ");
- console.log("args:");
- console.log(" --target ./path path to build folder");
- console.log("flags:");
- console.log(" --h print this help");
- console.log(" --m minify");
- console.log(" --nc namespace require");
- console.log(" --s shrinkwrap (combines all output files into one)");
- console.log("");
- if (type)
- console.log(" output for " + type + " generated in " + BUILD_DIR);
-}
+console.log("using targetDir '", targetDir, "'");
-function ace() {
- console.log('# ace License | Readme | Changelog ---------');
+var copy = require('./support/dryice/lib/dryice').copy;
- 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");
+var aceHome = __dirname;
+
+console.log('# ace ---------');
+
+var aceProject = [
+ aceHome
+];
+
+if (target == "normal") {
+ aceProject.push(aceHome + '/demo');
+
+ copy({
+ source: "build_support/editor.html",
+ dest: targetDir + '/editor.html'
+ });
- console.log('# ace ---------');
- for (var i = 0; i < 4; i++)
- buildAce({compress: i & 2, noconflict: i & 1});
+ demo();
+} else if(target == "bm") {
+ copy({
+ source: "build_support/editor_textarea.html",
+ dest: targetDir + '/editor.html'
+ });
+ copy({
+ source: "build_support/style.css",
+ dest: targetDir + '/style.css'
+ });
}
+var project = copy.createCommonJsProject(aceProject);
+
+
+function filterTextPlugin(text) {
+ return text.replace(/(['"])text\!/g, "$1text/");
+ /*return text
+ .replace(/define\(\s*['"]text\!\)/g, "text/")
+ .replace(/require\(\s*['"]text\!\)/g, "text/")*/
+}
+
+var ace = copy.createDataObject();
+copy({
+ source: [
+ target == "normal"
+ ? 'build_support/mini_require.js'
+ : 'build_support/mini_require_textarea.js'
+ ],
+ dest: ace
+});
+copy({
+ source: [
+ copy.source.commonjs({
+ project: project,
+ require: ["ace/ace"]
+ })
+ ],
+ filter: [ copy.filter.moduleDefines ],
+ dest: ace
+});
+copy({
+ source: {
+ root: project,
+ include: /.*\.css$/,
+ exclude: /tests?\//
+ },
+ filter: [ copy.filter.addDefines ],
+ dest: ace
+});
+copy({
+ source: [
+ target == "normal"
+ ? 'build_support/boot.js'
+ : 'build_support/boot_textarea.js'
+ ],
+ dest: ace
+});
+
+if (target == "normal") {
+ // Create the compressed and uncompressed output files
+ copy({
+ source: ace,
+ filter: [copy.filter.uglifyjs, filterTextPlugin],
+ dest: targetDir + '/src/ace.js'
+ });
+ copy({
+ source: ace,
+ filter: [filterTextPlugin],
+ dest: targetDir + '/src/ace-uncompressed.js'
+ });
+} else if (target == "bm") {
+ copy({
+ source: ace,
+ filter: [
+ shadow,
+ copy.filter.uglifyjs
+ ],
+ dest: targetDir + '/src/ace.js'
+ });
+ copy({
+ source: ace,
+ filter: [
+ shadow
+ ],
+ dest: targetDir + '/src/ace-uncompressed.js'
+ });
+}
+
+var modeThemeFilters;
+if (target == "normal") {
+ modeThemeFilters = [
+ copy.filter.moduleDefines,
+ copy.filter.uglifyjs,
+ filterTextPlugin
+ ];
+} else if (target == "bm") {
+ modeThemeFilters = [
+ copy.filter.moduleDefines,
+ shadow,
+ copy.filter.uglifyjs
+ ]
+}
+
+console.log('# ace modes ---------');
+
+project.assumeAllFilesLoaded();
+[
+ "css", "html", "javascript", "php", "python", "xml", "ruby", "java", "c_cpp",
+ "coffee", "perl", "csharp", "svg", "clojure", "scss", "json", "groovy",
+ "ocaml", "scala", "textile", "scad"
+].forEach(function(mode) {
+ console.log("mode " + mode);
+ copy({
+ source: [
+ copy.source.commonjs({
+ project: project.clone(),
+ require: [ 'ace/mode/' + mode ]
+ })
+ ],
+ filter: modeThemeFilters,
+ dest: targetDir + "/src/mode-" + mode + ".js"
+ });
+});
+
+console.log('# ace themes ---------');
+
+[
+ "clouds", "clouds_midnight", "cobalt", "crimson_editor", "dawn", "eclipse",
+ "idle_fingers", "kr_theme", "merbivore", "merbivore_soft",
+ "mono_industrial", "monokai", "pastel_on_dark", "solarized_dark",
+ "solarized_light", "textmate", "twilight", "vibrant_ink"
+].forEach(function(theme) {
+ copy({
+ source: [{
+ root: aceHome,
+ include: "ace/theme/" + theme + ".js"
+ }],
+ filter: modeThemeFilters,
+ dest: targetDir + "/src/theme-" + theme + ".js"
+ });
+});
+
+console.log('# ace License | Readme | Changelog ---------');
+
+copy({
+ source: aceHome + "/LICENSE",
+ dest: targetDir + '/LICENSE'
+});
+copy({
+ source: aceHome + "/Readme.md",
+ dest: targetDir + '/Readme.md'
+});
+copy({
+ source: aceHome + "/ChangeLog.txt",
+ dest: targetDir + '/ChangeLog.txt'
+});
+
+// For the bookmarklet build, we are done.
+if (target == "bm") {
+ process.exit(0);
+}
+
+console.log('# ace worker ---------');
+
+["javascript", "coffee", "css"].forEach(function(mode) {
+ console.log("worker for " + mode + " mode");
+ var worker = copy.createDataObject();
+ var workerProject = copy.createCommonJsProject([
+ aceHome
+ ]);
+ copy({
+ source: [
+ copy.source.commonjs({
+ project: workerProject,
+ require: [
+ 'ace/lib/fixoldbrowsers',
+ 'ace/lib/event_emitter',
+ 'ace/lib/oop',
+ 'ace/mode/' + mode + '_worker'
+ ]
+ })
+ ],
+ filter: [ copy.filter.moduleDefines],
+ dest: worker
+ });
+ copy({
+ source: [
+ aceHome + "/ace/worker/worker.js",
+ worker
+ ],
+ filter: [ copy.filter.uglifyjs, filterTextPlugin ],
+ dest: "build/src/worker-" + mode + ".js"
+ });
+});
+
+console.log('# ace key bindings ---------');
+
+// copy key bindings
+project.assumeAllFilesLoaded();
+["vim", "emacs"].forEach(function(keybinding) {
+ copy({
+ source: [
+ copy.source.commonjs({
+ project: project.clone(),
+ require: [ 'ace/keyboard/keybinding/' + keybinding ]
+ })
+ ],
+ filter: [ copy.filter.moduleDefines, copy.filter.uglifyjs, filterTextPlugin ],
+ dest: "build/src/keybinding-" + keybinding + ".js"
+ });
+});
+
function demo() {
console.log('# kitchen sink ---------');
- var version = "", ref = "";
- try {
- version = JSON.parse(fs.readFileSync(ACE_HOME + "/package.json")).version;
- ref = fs.readFileSync(ACE_HOME + "/.git-ref").toString();
- } catch(e) {}
-
- function changeComments(data) {
- return (data
- .replace("doc/site/images/ace-logo.png", "demo/kitchen-sink/ace-logo.png")
- .replace(//g, "")
- .replace(/PACKAGE\-\->|")}
- function script(str) {result.push('')}
- scripts.forEach(function(s) {
- s = s.replace(/"/g, "");
- if (s == "ace/ace") {
- comment("load ace");
- script("ace");
- } else {
- var extName = s.match(/[^/]*$/)[0];
- comment("load ace " + extName + " extension");
- script("ext-" + extName);
- }
- });
- result.push("
-```
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.
-```css
#editor {
position: absolute;
width: 500px;
height: 400px;
}
-```
+
To change the theme simply include the Theme's JavaScript file
-```html
-```
and configure the editor to use the theme:
-```javascript
editor.setTheme("ace/theme/twilight");
-```
By default the editor only supports plain text mode; many other languages are available as separate modules. After including the mode's JavaScript file:
-```html
-```
-The mode can then be used like this:
+Then the mode can be used like this:
-```javascript
- var JavaScriptMode = ace.require("ace/mode/javascript").Mode;
+ var JavaScriptMode = require("ace/mode/javascript").Mode;
editor.getSession().setMode(new JavaScriptMode());
-```
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 find a lot more sample code in the [demo app](https://github.com/ajaxorg/ace/blob/master/demo/demo.js).
-You can also find API documentation at [http://ace.c9.io/#nav=api](http://ace.c9.io/#nav=api).
+There is also some documentation on the [wiki page](https://github.com/ajaxorg/ace/wiki).
-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 drop a mail on the [ace mailing list](http://groups.google.com/group/ace-discuss).
Running Ace
-----------
-After the checkout Ace works out of the box. No build step is required. To try it out, simply start the bundled mini HTTP server:
+After the checkout Ace works out of the box. No build step is required. Open 'editor.html' in any browser except Google Chrome. Google Chrome doesn't allow XMLHTTPRequests from files loaded from disc (i.e. with a file:/// URL). To open Ace in Chrome simply start the bundled mini HTTP server:
-```bash
./static.py
-```
Or using Node.JS
-```bash
- npm install mime
- node ./static.js
-```
+ ./static.js
-The editor can then be opened at http://localhost:8888/kitchen-sink.html.
+The editor can then be opened at http://localhost:8888/index.html.
-To open the editor with a file:/// URL see [the wiki](https://github.com/ajaxorg/ace/wiki/Running-Ace-from-file).
-
-Building Ace
+Package Ace
-----------
-You do not generally need to build ACE. The [ace-builds repository](https://github.com/ajaxorg/ace-builds/) endeavours to maintain the latest build, and you can just copy one of _src*_ subdirectories somewhere into your project.
+To package Ace we use the dryice build tool developed by the Mozilla Skywriter team. Before you can build you need to make sure that the submodules are up to date.
-However, all you need is Node.js and npm installed to package ACE. Just run `npm install` in the ace folder to install dependencies:
+ git submodule update --init --recursive
-```bash
- npm install
- node ./Makefile.dryice.js
-```
+Afterwards Ace can be built by calling
-To package Ace, we use the dryice build tool developed by the Mozilla Skywriter team. Call `node Makefile.dryice.js` on the command-line to start the packing. This build script accepts the following options
+ ./Makefile.dryice.js normal
-```bash
--m minify build files with uglify-js
--nc namespace require and define calls with "ace"
--bm builds the bookmarklet version
---target ./path specify relative path for output folder (default value is "./build")
-```
+The packaged Ace will be put in the 'build' folder.
-To generate all the files in the ace-builds repository, run `node Makefile.dryice.js full --target ../ace-builds`
+To build the bookmarklet version execute
+
+ ./Makefile.dryice.js bm
Running the Unit Tests
----------------------
-The Ace unit tests can run on node.js. Assuming you have already done `npm install`, just call:
+The Ace unit tests run on node.js. Before the first run a couple of node modules have to be installed. The easiest way to do this is by using the node package manager (npm). In the Ace base directory simply call
+
+ npm link .
+
+To run the tests call:
-```bash
node lib/ace/test/all.js
-```
You can also run the tests in your browser by serving:
@@ -152,17 +139,23 @@ You can also run the tests in your browser by serving:
This makes debugging failing tests way more easier.
+_Note_: Currently (2011-05-21) the tests seem to run on Chrome only.
+
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!
+Ace wouldn't be where it is now without contributions. Feel free to fork and improve/enhance Ace in any way your 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:
-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. For more information on our contributing guidelines, see [CONTRIBUTING.md](https://github.com/ajaxorg/ace/blob/master/CONTRIBUTING.md).
+1. [The Individual CLA](https://github.com/ajaxorg/ace/raw/master/doc/Contributor_License_Agreement-v2.pdf): use this version if you're working on an ajax.org in your spare time, or can clearly claim ownership of copyright in what you'll be submitting.
+2. [The Corporate CLA](https://github.com/ajaxorg/ace/raw/master/doc/Corporate_Contributor_License_Agreement-v2.pdf): have your corporate lawyer review and submit this if your company is going to be contributing to ajax.org projects
-Continuous Integration status
------------------------------
+If you want to contribute to an ajax.org project please print the CLA and fill it out and sign it. Then either send it by snail mail or fax to us or send it back scanned (or as a photo) by email.
-This project is tested with [Travis CI](http://travis-ci.org)
-[](http://travis-ci.org/ajaxorg/ace)
+Email: fabian.jakobs@web.de
+Fax: +31 (0) 206388953
+Address: Ajax.org B.V.
+ Keizersgracht 241
+ 1016 EA, Amsterdam
+ the Netherlands
\ No newline at end of file
diff --git a/ace/ace.js b/ace/ace.js
new file mode 100644
index 00000000..350228b7
--- /dev/null
+++ b/ace/ace.js
@@ -0,0 +1,77 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Kevin Dangoor (kdangoor@mozilla.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+ require("ace/lib/fixoldbrowsers");
+
+ var Dom = require("ace/lib/dom");
+ var Event = require("ace/lib/event");
+
+ var Editor = require("ace/editor").Editor;
+ var Buffer = require("ace/model/buffer").Buffer;
+ var Window = require("ace/model/window").Window;
+ var UndoManager = require("ace/undomanager").UndoManager;
+ var Renderer = require("ace/view/window_view").WindowView;
+
+ exports.edit = function(el) {
+ if (typeof(el) == "string") {
+ el = document.getElementById(el);
+ }
+
+ var doc = new Buffer(Dom.getInnerText(el));
+ doc.setUndoManager(new UndoManager());
+ el.innerHTML = '';
+
+ var theme = require("ace/theme/textmate");
+ var editor = new Editor(new Renderer(new Window(theme), el));
+ editor.setSession(doc);
+
+ var env = {};
+ env.document = doc;
+ env.editor = editor;
+ editor.resize();
+ Event.addListener(window, "resize", function() {
+ editor.resize();
+ });
+ el.env = env;
+ // Store env on editor such that it can be accessed later on from
+ // the returned object.
+ editor.env = env;
+ return editor;
+ };
+});
\ No newline at end of file
diff --git a/ace/anchor.js b/ace/anchor.js
new file mode 100644
index 00000000..caa732f2
--- /dev/null
+++ b/ace/anchor.js
@@ -0,0 +1,192 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var EventEmitter = require("ace/lib/event_emitter").EventEmitter;
+
+/**
+ * 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
+ */
+var Anchor = exports.Anchor = function(doc, row, column) {
+ this.document = doc;
+
+ if (typeof column == "undefined")
+ this.setPosition(row.row, row.column);
+ else
+ this.setPosition(row, column);
+
+ this.$onChange = this.onChange.bind(this);
+ doc.on("change", this.$onChange);
+};
+
+(function() {
+
+ oop.implement(this, EventEmitter);
+
+ this.getPosition = function() {
+ return this.$clipPositionToDocument(this.row, this.column);
+ };
+
+ this.getDocument = function() {
+ return this.document;
+ };
+
+ this.onChange = function(e) {
+ var delta = e.data;
+ var range = delta.range;
+
+ if (range.start.row == range.end.row && range.start.row != this.row)
+ return;
+
+ if (range.start.row > this.row)
+ return;
+
+ if (range.start.row == this.row && range.start.column > this.column)
+ return;
+
+ var row = this.row;
+ var column = this.column;
+
+ if (delta.action === "insertText") {
+ if (range.start.row === row && range.start.column <= column) {
+ if (range.start.row === range.end.row) {
+ column += range.end.column - range.start.column;
+ }
+ else {
+ column -= range.start.column;
+ row += range.end.row - range.start.row;
+ }
+ }
+ else if (range.start.row !== range.end.row && range.start.row < row) {
+ row += range.end.row - range.start.row;
+ }
+ } else if (delta.action === "insertLines") {
+ if (range.start.row <= row) {
+ row += range.end.row - range.start.row;
+ }
+ }
+ else if (delta.action == "removeText") {
+ if (range.start.row == row && range.start.column < column) {
+ if (range.end.column >= column)
+ column = range.start.column;
+ else
+ column = Math.max(0, column - (range.end.column - range.start.column));
+
+ } else if (range.start.row !== range.end.row && range.start.row < row) {
+ if (range.end.row == row) {
+ column = Math.max(0, column - range.end.column) + range.start.column;
+ }
+ row -= (range.end.row - range.start.row);
+ }
+ else if (range.end.row == row) {
+ row -= range.end.row - range.start.row;
+ column = Math.max(0, column - range.end.column) + range.start.column;
+ }
+ } else if (delta.action == "removeLines") {
+ if (range.start.row <= row) {
+ if (range.end.row <= row)
+ row -= range.end.row - range.start.row;
+ else {
+ row = range.start.row;
+ column = 0;
+ }
+ }
+ }
+
+ this.setPosition(row, column, true);
+ };
+
+ this.setPosition = function(row, column, noClip) {
+ var pos;
+ if (noClip) {
+ pos = {
+ row: row,
+ column: column
+ };
+ }
+ else {
+ pos = this.$clipPositionToDocument(row, column);
+ }
+
+ if (this.row == pos.row && this.column == pos.column)
+ return;
+
+ var old = {
+ row: this.row,
+ column: this.column
+ };
+
+ this.row = pos.row;
+ this.column = pos.column;
+ this._dispatchEvent("change", {
+ old: old,
+ value: pos
+ });
+ };
+
+ this.detach = function() {
+ this.document.removeEventListener("change", this.$onChange);
+ };
+
+ this.$clipPositionToDocument = function(row, column) {
+ var pos = {};
+
+ if (row >= this.document.getLength()) {
+ pos.row = Math.max(0, this.document.getLength() - 1);
+ pos.column = this.document.getLine(pos.row).length;
+ }
+ else if (row < 0) {
+ pos.row = 0;
+ pos.column = 0;
+ }
+ else {
+ pos.row = row;
+ pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
+ }
+
+ if (column < 0)
+ pos.column = 0;
+
+ return pos;
+ };
+
+}).call(Anchor.prototype);
+
+});
diff --git a/lib/ace/anchor_test.js b/ace/anchor_test.js
similarity index 54%
rename from lib/ace/anchor_test.js
rename to ace/anchor_test.js
index c0b97273..88a3255b 100644
--- a/lib/ace/anchor_test.js
+++ b/ace/anchor_test.js
@@ -1,44 +1,50 @@
/* ***** BEGIN LICENSE BLOCK *****
- * Distributed under the BSD license:
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
- * 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.
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
if (typeof process !== "undefined") {
- require("amd-loader");
+ require("../support/paths");
}
define(function(require, exports, module) {
-"use strict";
-
-var Document = require("./document").Document;
-var Anchor = require("./anchor").Anchor;
-var Range = require("./range").Range;
-var assert = require("./test/assertions");
+
+var Document = require("ace/model/document").Document;
+var Anchor = require("ace/anchor").Anchor;
+var Range = require("ace/range").Range;
+var assert = require("ace/test/assertions");
module.exports = {
@@ -57,55 +63,20 @@ module.exports = {
doc.insert({row: 1, column: 1}, "123");
assert.position(anchor.getPosition(), 1, 7);
},
-
- "test insert text at anchor should not move anchor when insertRight is true": function() {
- var doc = new Document("juhu\nkinners");
- var anchor = new Anchor(doc, 1, 4);
- anchor.$insertRight = true;
-
- doc.insert({row: 1, column: 4}, "123");
- assert.position(anchor.getPosition(), 1, 4);
- },
"test insert lines before cursor should move anchor row": function() {
var doc = new Document("juhu\nkinners");
var anchor = new Anchor(doc, 1, 4);
- doc.insertFullLines(1, ["123", "456"]);
+ doc.insertLines(1, ["123", "456"]);
assert.position(anchor.getPosition(), 3, 4);
},
-
- "test insert lines at anchor position should move anchor down": function() {
- var doc = new Document("juhu\nkinners");
- var anchor = new Anchor(doc, 1, 0);
-
- doc.insertLines(1, ["line"]);
- assert.position(anchor.getPosition(), 2, 0);
- },
-
- "test insert lines at anchor position should not move anchor down when insertRight is true and column is 0": function() {
- var doc = new Document("juhu\nkinners");
- var anchor = new Anchor(doc, 1, 0);
- anchor.$insertRight = true;
-
- doc.insertLines(1, ["line"]);
- assert.position(anchor.getPosition(), 1, 0);
- },
-
- "test insert lines at anchor row should move anchor down when column > 0": function() {
- var doc = new Document("juhu\nkinners");
- var anchor = new Anchor(doc, 1, 2);
- anchor.$insertRight = true;
-
- doc.insertLines(1, ["line"]);
- assert.position(anchor.getPosition(), 2, 2);
- },
"test insert new line before cursor should move anchor column": function() {
var doc = new Document("juhu\nkinners");
var anchor = new Anchor(doc, 1, 4);
- doc.insertMergedLines({row: 0, column: 0}, ['', '']);
+ doc.insertNewLine({row: 0, column: 0});
assert.position(anchor.getPosition(), 2, 4);
},
@@ -113,7 +84,7 @@ module.exports = {
var doc = new Document("juhu\nkinners");
var anchor = new Anchor(doc, 1, 4);
- doc.insertMergedLines({row: 1, column: 2}, ['', '']);
+ doc.insertNewLine({row: 1, column: 2});
assert.position(anchor.getPosition(), 2, 2);
},
@@ -145,7 +116,7 @@ module.exports = {
var doc = new Document("juhu\n1\n2\nkinners");
var anchor = new Anchor(doc, 3, 4);
- doc.removeFullLines(1, 2);
+ doc.removeLines(1, 2);
assert.position(anchor.getPosition(), 1, 4);
},
@@ -169,7 +140,7 @@ module.exports = {
var doc = new Document("juhu\nkinners\n123");
var anchor = new Anchor(doc, 1, 5);
- doc.removeFullLines(1, 1);
+ doc.removeLines(1, 1);
assert.position(anchor.getPosition(), 1, 0);
},
@@ -202,17 +173,6 @@ module.exports = {
});
doc.remove(new Range(2, 0, 2, 1));
- },
-
- "test insert/remove lines at the end of the document": function() {
- var doc = new Document("juhu\nkinners\n123");
- var anchor = new Anchor(doc, 2, 4);
-
- doc.removeFullLines(0, 3);
- assert.position(anchor.getPosition(), 0, 0);
- doc.insertFullLines(0, ["a", "b", "c"]);
- assert.position(anchor.getPosition(), 3, 0);
- assert.equal(doc.getValue(), "a\nb\nc\n");
}
};
@@ -220,4 +180,4 @@ module.exports = {
if (typeof module !== "undefined" && module === require.main) {
require("asyncjs").test.testcase(module.exports).exec()
-}
+}
\ No newline at end of file
diff --git a/ace/background_tokenizer.js b/ace/background_tokenizer.js
new file mode 100644
index 00000000..96688b2f
--- /dev/null
+++ b/ace/background_tokenizer.js
@@ -0,0 +1,175 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var EventEmitter = require("ace/lib/event_emitter").EventEmitter;
+
+var BackgroundTokenizer = function(tokenizer, editor) {
+ this.running = false;
+ this.lines = [];
+ this.currentLine = 0;
+ this.tokenizer = tokenizer;
+
+ var self = this;
+
+ this.$worker = function() {
+ if (!self.running) { return; }
+
+ var workerStart = new Date();
+ var startLine = self.currentLine;
+ var doc = self.doc;
+
+ var processedLines = 0;
+
+ var len = doc.getLength();
+ while (self.currentLine < len) {
+ self.lines[self.currentLine] = self.$tokenizeRows(self.currentLine, self.currentLine)[0];
+ self.currentLine++;
+
+ // only check every 5 lines
+ processedLines += 1;
+ if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {
+ self.fireUpdateEvent(startLine, self.currentLine-1);
+ self.running = setTimeout(self.$worker, 20);
+ return;
+ }
+ }
+
+ self.running = false;
+
+ self.fireUpdateEvent(startLine, len - 1);
+ };
+};
+
+(function(){
+
+ oop.implement(this, EventEmitter);
+
+ this.setTokenizer = function(tokenizer) {
+ this.tokenizer = tokenizer;
+ this.lines = [];
+
+ this.start(0);
+ };
+
+ this.setDocument = function(doc) {
+ this.doc = doc;
+ this.lines = [];
+
+ this.stop();
+ };
+
+ this.fireUpdateEvent = function(firstRow, lastRow) {
+ var data = {
+ first: firstRow,
+ last: lastRow
+ };
+ this._dispatchEvent("update", {data: data});
+ };
+
+ this.start = function(startRow) {
+ this.currentLine = Math.min(startRow || 0, this.currentLine,
+ this.doc.getLength());
+
+ // remove all cached items below this line
+ this.lines.splice(this.currentLine, this.lines.length);
+
+ this.stop();
+ // pretty long delay to prevent the tokenizer from interfering with the user
+ this.running = setTimeout(this.$worker, 700);
+ };
+
+ this.stop = function() {
+ if (this.running)
+ clearTimeout(this.running);
+ this.running = false;
+ };
+
+ this.getTokens = function(firstRow, lastRow) {
+ return this.$tokenizeRows(firstRow, lastRow);
+ };
+
+ this.getState = function(row) {
+ return this.$tokenizeRows(row, row)[0].state;
+ };
+
+ this.$tokenizeRows = function(firstRow, lastRow) {
+ if (!this.doc)
+ return [];
+
+ var rows = [];
+
+ // determine start state
+ var state = "start";
+ var doCache = false;
+ if (firstRow > 0 && this.lines[firstRow - 1]) {
+ state = this.lines[firstRow - 1].state;
+ doCache = true;
+ } else if (firstRow == 0) {
+ state = "start";
+ doCache = true;
+ } else if (this.lines.length > 0) {
+ // Guess that we haven't changed state.
+ state = this.lines[this.lines.length-1].state;
+ }
+
+ var lines = this.doc.getLines(firstRow, lastRow);
+ for (var row=firstRow; row<=lastRow; row++) {
+ if (!this.lines[row]) {
+ var tokens = this.tokenizer.getLineTokens(lines[row-firstRow] || "", state);
+ var state = tokens.state;
+ rows.push(tokens);
+
+ if (doCache) {
+ this.lines[row] = tokens;
+ }
+ }
+ else {
+ var tokens = this.lines[row];
+ state = tokens.state;
+ rows.push(tokens);
+ }
+ }
+ return rows;
+ };
+
+}).call(BackgroundTokenizer.prototype);
+
+exports.BackgroundTokenizer = BackgroundTokenizer;
+});
diff --git a/ace/commands/command_manager.js b/ace/commands/command_manager.js
new file mode 100644
index 00000000..36b7c273
--- /dev/null
+++ b/ace/commands/command_manager.js
@@ -0,0 +1,87 @@
+define(function(require, exports, module) {
+
+var keyUtil = require("ace/lib/keys");
+var useragent = require("ace/lib/useragent");
+
+var CommandManager = function(commands) {
+ this.commands = {};
+ this.commmandKeyBinding = {};
+
+ if (commands)
+ commands.forEach(this.addCommand, this);
+};
+
+(function() {
+
+ this.addCommand = function(command) {
+ this.commands[command.name] = command;
+
+ if (command.bindKey) {
+ this._buildKeyHash(command);
+ }
+ };
+
+ var platform = useragent.isMac ? "mac" : "win";
+
+ this._buildKeyHash = function(command) {
+ var binding = command.bindKey;
+ var key = binding[platform];
+ var ckb = this.commmandKeyBinding;
+
+ if(!binding[platform]) {
+ return;
+ }
+
+ key.split("|").forEach(function(keyPart) {
+ var binding = parseKeys(keyPart, command);
+ var hashId = binding.hashId;
+ (ckb[hashId] || (ckb[hashId] = {}))[binding.key] = command;
+ });
+ }
+
+ function parseKeys(keys, val, ret) {
+ var key;
+ var hashId = 0;
+ var parts = splitSafe(keys, "\\-", null, true);
+
+ for (var i=0, l = parts.length; i < l; i++) {
+ if (keyUtil.KEY_MODS[parts[i]])
+ hashId = hashId | keyUtil.KEY_MODS[parts[i]];
+ else
+ key = parts[i] || "-"; //when empty, the splitSafe removed a '-'
+ }
+
+ return {
+ key: key,
+ hashId: hashId
+ }
+ }
+
+ function splitSafe(s, separator, limit, bLowerCase) {
+ return (bLowerCase && s.toLowerCase() || s)
+ .replace(/(?:^\s+|\n|\s+$)/g, "")
+ .split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999);
+ }
+
+ this.findKeyCommand = function findKeyCommand(env, hashId, textOrKey) {
+ // Convert keyCode to the string representation.
+ if (typeof textOrKey == "number") {
+ textOrKey = keyUtil.keyCodeToString(textOrKey);
+ }
+
+ var ckbr = this.commmandKeyBinding;
+ return ckbr[hashId] && ckbr[hashId][textOrKey];
+ }
+
+ this.exec = function(command, env, args) {
+ if (typeof command === 'string')
+ command = this.commands[command];
+
+ command.exec(env, args || {});
+ };
+
+}).call(CommandManager.prototype);
+
+exports.CommandManager = CommandManager;
+
+});
diff --git a/ace/commands/default_commands.js b/ace/commands/default_commands.js
new file mode 100644
index 00000000..67447632
--- /dev/null
+++ b/ace/commands/default_commands.js
@@ -0,0 +1,307 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Julian Viereck
+ * Mihai Sucan
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var lang = require("ace/lib/lang");
+
+function bindKey(win, mac) {
+ return {
+ win: win,
+ mac: mac,
+ sender: "editor"
+ };
+}
+
+exports.commands = [{
+ name: "selectall",
+ bindKey: bindKey("Ctrl-A", "Command-A"),
+ exec: function(env, args) { env.editor.selectAll(); }
+}, {
+ name: "removeline",
+ bindKey: bindKey("Ctrl-D", "Command-D"),
+ exec: function(env, args) { env.editor.removeLines(); }
+}, {
+ name: "gotoline",
+ bindKey: bindKey("Ctrl-L", "Command-L"),
+ exec: function(env, args) {
+ var line = parseInt(prompt("Enter line number:"));
+ if (!isNaN(line)) {
+ env.editor.gotoLine(line);
+ }
+ }
+}, {
+ name: "togglecomment",
+ bindKey: bindKey("Ctrl-7", "Command-7"),
+ exec: function(env, args) { env.editor.toggleCommentLines(); }
+}, {
+ name: "findnext",
+ bindKey: bindKey("Ctrl-K", "Command-G"),
+ exec: function(env, args) { env.editor.findNext(); }
+}, {
+ name: "findprevious",
+ bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
+ exec: function(env, args) { env.editor.findPrevious(); }
+}, {
+ name: "find",
+ bindKey: bindKey("Ctrl-F", "Command-F"),
+ exec: function(env, args) {
+ var needle = prompt("Find:");
+ env.editor.find(needle);
+ }
+}, {
+ name: "replace",
+ bindKey: bindKey("Ctrl-R", "Command-Option-F"),
+ exec: function(env, args) {
+ var needle = prompt("Find:");
+ if (!needle)
+ return;
+ var replacement = prompt("Replacement:");
+ if (!replacement)
+ return;
+ env.editor.replace(replacement, {needle: needle});
+ }
+}, {
+ name: "replaceall",
+ bindKey: bindKey("Ctrl-Shift-R", "Command-Shift-Option-F"),
+ exec: function(env, args) {
+ var needle = prompt("Find:");
+ if (!needle)
+ return;
+ var replacement = prompt("Replacement:");
+ if (!replacement)
+ return;
+ env.editor.replaceAll(replacement, {needle: needle});
+ }
+}, {
+ name: "undo",
+ bindKey: bindKey("Ctrl-Z", "Command-Z"),
+ exec: function(env, args) { env.editor.undo(); }
+}, {
+ name: "redo",
+ bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
+ exec: function(env, args) { env.editor.redo(); }
+}, {
+ name: "overwrite",
+ bindKey: bindKey("Insert", "Insert"),
+ exec: function(env, args) { env.editor.toggleOverwrite(); }
+}, {
+ name: "copylinesup",
+ bindKey: bindKey("Ctrl-Alt-Up", "Command-Option-Up"),
+ exec: function(env, args) { env.editor.copyLinesUp(); }
+}, {
+ name: "movelinesup",
+ bindKey: bindKey("Alt-Up", "Option-Up"),
+ exec: function(env, args) { env.editor.moveLinesUp(); }
+}, {
+ name: "selecttostart",
+ bindKey: bindKey("Ctrl-Shift-Home|Alt-Shift-Up", "Command-Shift-Up"),
+ exec: function(env, args) { env.editor.getSelection().selectFileStart(); }
+}, {
+ name: "gotostart",
+ bindKey: bindKey("Ctrl-Home|Ctrl-Up", "Command-Home|Command-Up"),
+ exec: function(env, args) { env.editor.navigateFileStart(); }
+}, {
+ name: "selectup",
+ bindKey: bindKey("Shift-Up", "Shift-Up"),
+ exec: function(env, args) { env.editor.getSelection().selectUp(); }
+}, {
+ name: "golineup",
+ bindKey: bindKey("Up", "Up|Ctrl-P"),
+ exec: function(env, args) { env.editor.navigateUp(args.times); }
+}, {
+ name: "copylinesdown",
+ bindKey: bindKey("Ctrl-Alt-Down", "Command-Option-Down"),
+ exec: function(env, args) { env.editor.copyLinesDown(); }
+}, {
+ name: "movelinesdown",
+ bindKey: bindKey("Alt-Down", "Option-Down"),
+ exec: function(env, args) { env.editor.moveLinesDown(); }
+}, {
+ name: "selecttoend",
+ bindKey: bindKey("Ctrl-Shift-End|Alt-Shift-Down", "Command-Shift-Down"),
+ exec: function(env, args) { env.editor.getSelection().selectFileEnd(); }
+}, {
+ name: "gotoend",
+ bindKey: bindKey("Ctrl-End|Ctrl-Down", "Command-End|Command-Down"),
+ exec: function(env, args) { env.editor.navigateFileEnd(); }
+}, {
+ name: "selectdown",
+ bindKey: bindKey("Shift-Down", "Shift-Down"),
+ exec: function(env, args) { env.editor.getSelection().selectDown(); }
+}, {
+ name: "golinedown",
+ bindKey: bindKey("Down", "Down|Ctrl-N"),
+ exec: function(env, args) { env.editor.navigateDown(args.times); }
+}, {
+ name: "selectwordleft",
+ bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
+ exec: function(env, args) { env.editor.getSelection().selectWordLeft(); }
+}, {
+ name: "gotowordleft",
+ bindKey: bindKey("Ctrl-Left", "Option-Left"),
+ exec: function(env, args) { env.editor.navigateWordLeft(); }
+}, {
+ name: "selecttolinestart",
+ bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"),
+ exec: function(env, args) { env.editor.getSelection().selectLineStart(); }
+}, {
+ name: "gotolinestart",
+ bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
+ exec: function(env, args) { env.editor.navigateLineStart(); }
+}, {
+ name: "selectleft",
+ bindKey: bindKey("Shift-Left", "Shift-Left"),
+ exec: function(env, args) { env.editor.getSelection().selectLeft(); }
+}, {
+ name: "gotoleft",
+ bindKey: bindKey("Left", "Left|Ctrl-B"),
+ exec: function(env, args) { env.editor.navigateLeft(args.times); }
+}, {
+ name: "selectwordright",
+ bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
+ exec: function(env, args) { env.editor.getSelection().selectWordRight(); }
+}, {
+ name: "gotowordright",
+ bindKey: bindKey("Ctrl-Right", "Option-Right"),
+ exec: function(env, args) { env.editor.navigateWordRight(); }
+}, {
+ name: "selecttolineend",
+ bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"),
+ exec: function(env, args) { env.editor.getSelection().selectLineEnd(); }
+}, {
+ name: "gotolineend",
+ bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
+ exec: function(env, args) { env.editor.navigateLineEnd(); }
+}, {
+ name: "selectright",
+ bindKey: bindKey("Shift-Right", "Shift-Right"),
+ exec: function(env, args) { env.editor.getSelection().selectRight(); }
+}, {
+ name: "gotoright",
+ bindKey: bindKey("Right", "Right|Ctrl-F"),
+ exec: function(env, args) { env.editor.navigateRight(args.times); }
+}, {
+ name: "selectpagedown",
+ bindKey: bindKey("Shift-PageDown", "Shift-PageDown"),
+ exec: function(env, args) { env.editor.selectPageDown(); }
+}, {
+ name: "pagedown",
+ bindKey: bindKey(null, "PageDown"),
+ exec: function(env, args) { env.editor.scrollPageDown(); }
+}, {
+ name: "gotopagedown",
+ bindKey: bindKey("PageDown", "Option-PageDown|Ctrl-V"),
+ exec: function(env, args) { env.editor.gotoPageDown(); }
+}, {
+ name: "selectpageup",
+ bindKey: bindKey("Shift-PageUp", "Shift-PageUp"),
+ exec: function(env, args) { env.editor.selectPageUp(); }
+}, {
+ name: "pageup",
+ bindKey: bindKey(null, "PageUp"),
+ exec: function(env, args) { env.editor.scrollPageUp(); }
+}, {
+ name: "gotopageup",
+ bindKey: bindKey("PageUp", "Option-PageUp"),
+ exec: function(env, args) { env.editor.gotoPageUp(); }
+}, {
+ name: "selectlinestart",
+ bindKey: bindKey("Shift-Home", "Shift-Home"),
+ exec: function(env, args) { env.editor.getSelection().selectLineStart(); }
+}, {
+ name: "selectlineend",
+ bindKey: bindKey("Shift-End", "Shift-End"),
+ exec: function(env, args) { env.editor.getSelection().selectLineEnd(); }
+}, {
+ name: "del",
+ bindKey: bindKey("Delete", "Delete|Ctrl-D"),
+ exec: function(env, args) { env.editor.removeRight(); }
+}, {
+ name: "backspace",
+ bindKey: bindKey(
+ "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
+ "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H"
+ ),
+ exec: function(env, args) { env.editor.removeLeft(); }
+}, {
+ name: "removetolinestart",
+ bindKey: bindKey(null, "Option-Backspace"),
+ exec: function(env, args) { env.editor.removeToLineStart(); }
+}, {
+ name: "removetolineend",
+ bindKey: bindKey(null, "Ctrl-K"),
+ exec: function(env, args) { env.editor.removeToLineEnd(); }
+}, {
+ name: "removewordleft",
+ bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
+ exec: function(env, args) { env.editor.removeWordLeft(); }
+}, {
+ name: "removewordright",
+ bindKey: bindKey(null, "Alt-Delete"),
+ exec: function(env, args) { env.editor.removeWordRight(); }
+}, {
+ name: "outdent",
+ bindKey: bindKey("Shift-Tab", "Shift-Tab"),
+ exec: function(env, args) { env.editor.blockOutdent(); }
+}, {
+ name: "indent",
+ bindKey: bindKey("Tab", "Tab"),
+ exec: function(env, args) { env.editor.indent(); }
+}, {
+ name: "inserttext",
+ exec: function(env, args) {
+ env.editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
+ }
+}, {
+ name: "centerselection",
+ bindKey: bindKey(null, "Ctrl-L"),
+ exec: function(env, args) { env.editor.centerSelection(); }
+}, {
+ name: "splitline",
+ bindKey: bindKey(null, "Ctrl-O"),
+ exec: function(env, args) { env.editor.splitLine(); }
+}, {
+ name: "transposeletters",
+ bindKey: bindKey("Ctrl-T", "Ctrl-T"),
+ exec: function(env, args) { env.editor.transposeLetters(); }
+}];
+
+});
\ No newline at end of file
diff --git a/ace/edit_session/fold.js b/ace/edit_session/fold.js
new file mode 100644
index 00000000..bb9d98e7
--- /dev/null
+++ b/ace/edit_session/fold.js
@@ -0,0 +1,79 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Julian Viereck
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+/**
+ * Simple fold-data struct.
+ **/
+var Fold = exports.Fold = function(range, placeholder) {
+ this.foldLine = null;
+ this.placeholder = placeholder;
+ this.range = range;
+ this.start = range.start;
+ this.end = range.end;
+
+ this.sameRow = range.start.row == range.end.row;
+ this.subFolds = [];
+};
+
+(function() {
+
+ this.toString = function() {
+ return '"' + this.placeholder + '" ' + this.range.toString();
+ };
+
+ this.setFoldLine = function(foldLine) {
+ this.foldLine = foldLine;
+ this.subFolds.forEach(function(fold) {
+ fold.setFoldLine(foldLine);
+ });
+ };
+
+ this.clone = function() {
+ var range = this.range.clone();
+ var fold = new Fold(range, this.placeholder);
+ this.subFolds.forEach(function(subFold) {
+ fold.subFolds.push(subFold.clone());
+ });
+ return fold;
+ };
+
+}).call(Fold.prototype);
+
+});
\ No newline at end of file
diff --git a/lib/ace/edit_session/fold_line.js b/ace/edit_session/fold_line.js
similarity index 70%
rename from lib/ace/edit_session/fold_line.js
rename to ace/edit_session/fold_line.js
index 9d73154d..7e017a8c 100644
--- a/lib/ace/edit_session/fold_line.js
+++ b/ace/edit_session/fold_line.js
@@ -1,40 +1,47 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Distributed under the BSD license:
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
- * 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.
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Julian Viereck
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
-"use strict";
-var Range = require("../range").Range;
+var Range = require("ace/range").Range;
-/*
- * If an array is passed in, the folds are expected to be sorted already.
+/**
+ * If the an array is passed in, the folds are expected to be sorted already.
*/
function FoldLine(foldData, folds) {
this.foldData = foldData;
@@ -44,7 +51,7 @@ function FoldLine(foldData, folds) {
folds = this.folds = [ folds ];
}
- var last = folds[folds.length - 1];
+ var last = folds[folds.length - 1]
this.range = new Range(folds[0].start.row, folds[0].start.column,
last.end.row, last.end.column);
this.start = this.range.start;
@@ -56,7 +63,7 @@ function FoldLine(foldData, folds) {
}
(function() {
- /*
+ /**
* Note: This doesn't update wrapData!
*/
this.shiftRow = function(shift) {
@@ -66,12 +73,12 @@ function FoldLine(foldData, folds) {
fold.start.row += shift;
fold.end.row += shift;
});
- };
+ }
this.addFold = function(fold) {
if (fold.sameRow) {
if (fold.start.row < this.startRow || fold.endRow > this.endRow) {
- throw new Error("Can't add a fold to this FoldLine as it has no connection");
+ throw "Can't add a fold to this FoldLine as it has no connection";
}
this.folds.push(fold);
this.folds.sort(function(a, b) {
@@ -93,20 +100,20 @@ function FoldLine(foldData, folds) {
this.start.row = fold.start.row;
this.start.column = fold.start.column;
} else {
- throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");
+ throw "Trying to add fold to FoldRow that doesn't have a matching row";
}
fold.foldLine = this;
- };
+ }
this.containsRow = function(row) {
return row >= this.start.row && row <= this.end.row;
- };
+ }
this.walk = function(callback, endRow, endColumn) {
var lastEnd = 0,
folds = this.folds,
fold,
- cmp, stop, isNewRow = true;
+ comp, stop, isNewRow = true;
if (endRow == null) {
endRow = this.end.row;
@@ -116,9 +123,9 @@ function FoldLine(foldData, folds) {
for (var i = 0; i < folds.length; i++) {
fold = folds[i];
- cmp = fold.range.compareStart(endRow, endColumn);
+ comp = fold.range.compareStart(endRow, endColumn);
// This fold is after the endRow/Column.
- if (cmp == -1) {
+ if (comp == -1) {
callback(null, endRow, endColumn, lastEnd, isNewRow);
return;
}
@@ -127,8 +134,8 @@ function FoldLine(foldData, folds) {
stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);
// If the user requested to stop the walk or endRow/endColumn is
- // inside of this fold (cmp == 0), then end here.
- if (stop || cmp === 0) {
+ // inside of this fold (comp == 0), then end here.
+ if (stop || comp == 0) {
return;
}
@@ -138,7 +145,7 @@ function FoldLine(foldData, folds) {
lastEnd = fold.end.column;
}
callback(null, endRow, endColumn, lastEnd, isNewRow);
- };
+ }
this.getNextFoldTo = function(row, column) {
var fold, cmp;
@@ -150,15 +157,15 @@ function FoldLine(foldData, folds) {
fold: fold,
kind: "after"
};
- } else if (cmp === 0) {
+ } else if (cmp == 0) {
return {
fold: fold,
kind: "inside"
- };
+ }
}
}
return null;
- };
+ }
this.addRemoveChars = function(row, column, len) {
var ret = this.getNextFoldTo(row, column),
@@ -169,13 +176,11 @@ function FoldLine(foldData, folds) {
&& fold.start.column != column
&& fold.start.row != row)
{
- //throwing here breaks whole editor
- //TODO: properly handle this
- window.console && window.console.log(row, column, fold);
+ throw "Moving characters inside of a fold should never be reached";
} else if (fold.start.row == row) {
folds = this.folds;
var i = folds.indexOf(fold);
- if (i === 0) {
+ if (i == 0) {
this.start.column += len;
}
for (i; i < folds.length; i++) {
@@ -189,18 +194,16 @@ function FoldLine(foldData, folds) {
this.end.column += len;
}
}
- };
+ }
this.split = function(row, column) {
- var pos = this.getNextFoldTo(row, column);
-
- if (!pos || pos.kind == "inside")
- return null;
-
- var fold = pos.fold;
- var folds = this.folds;
+ var fold = this.getNextFoldTo(row, column).fold,
+ folds = this.folds;
var foldData = this.foldData;
-
+
+ if (!fold) {
+ return null;
+ }
var i = folds.indexOf(fold);
var foldBefore = folds[i - 1];
this.end.row = foldBefore.end.row;
@@ -213,7 +216,7 @@ function FoldLine(foldData, folds) {
var newFoldLine = new FoldLine(foldData, folds);
foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
return newFoldLine;
- };
+ }
this.merge = function(foldLineNext) {
var folds = foldLineNext.folds;
@@ -224,7 +227,7 @@ function FoldLine(foldData, folds) {
// it's merged now with foldLineNext.
var foldData = this.foldData;
foldData.splice(foldData.indexOf(foldLineNext), 1);
- };
+ }
this.toString = function() {
var ret = [this.range.toString() + ": [" ];
@@ -232,12 +235,13 @@ function FoldLine(foldData, folds) {
this.folds.forEach(function(fold) {
ret.push(" " + fold.toString());
});
- ret.push("]");
+ ret.push("]")
return ret.join("\n");
- };
+ }
this.idxToPosition = function(idx) {
var lastFoldEndColumn = 0;
+ var fold;
for (var i = 0; i < this.folds.length; i++) {
var fold = this.folds[i];
@@ -262,8 +266,8 @@ function FoldLine(foldData, folds) {
row: this.end.row,
column: this.end.column + idx
};
- };
+ }
}).call(FoldLine.prototype);
exports.FoldLine = FoldLine;
-});
+});
\ No newline at end of file
diff --git a/ace/edit_session/folding.js b/ace/edit_session/folding.js
new file mode 100644
index 00000000..127081b5
--- /dev/null
+++ b/ace/edit_session/folding.js
@@ -0,0 +1,496 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Julian Viereck
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var Range = require("ace/range").Range;
+var FoldLine = require("ace/edit_session/fold_line").FoldLine;
+var Fold = require("ace/edit_session/fold").Fold;
+
+function 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
+ */
+ this.getFoldAt = function(row, column, side) {
+ var foldLine = this.getFoldLine(row);
+ if (!foldLine)
+ return null;
+
+ var folds = foldLine.folds;
+ for (var i = 0; i < folds.length; i++) {
+ var fold = folds[i];
+ if (fold.range.contains(row, column)) {
+ if (side == 1 && fold.range.isEnd(row, column)) {
+ continue;
+ } else if (side == -1 && fold.range.isStart(row, column)) {
+ continue;
+ }
+ return fold;
+ }
+ }
+ };
+
+ /**
+ * Returns all folds in the given range. Note, that this will return folds
+ *
+ */
+ this.getFoldsInRange = function(range) {
+ range = range.clone();
+ var start = range.start;
+ var end = range.end;
+ var foldLines = this.$foldData;
+ var foundFolds = [];
+
+ start.column += 1;
+ end.column -= 1;
+
+ for (var i = 0; i < foldLines.length; i++) {
+ var cmp = foldLines[i].range.compareRange(range);
+ if (cmp == 2) {
+ // Range is before foldLine. No intersection. This means,
+ // there might be other foldLines that intersect.
+ continue;
+ }
+ else if (cmp == -2) {
+ // Range is after foldLine. There can't be any other foldLines then,
+ // so let's give up.
+ break;
+ }
+
+ var folds = foldLines[i].folds;
+ for (var j = 0; j < folds.length; j++) {
+ var fold = folds[j];
+ cmp = fold.range.compareRange(range);
+ if (cmp == -2) {
+ break;
+ } else if (cmp == 2) {
+ continue;
+ } else
+ // WTF-state: Can happen due to -1/+1 to start/end column.
+ if (cmp == 42) {
+ break;
+ }
+ foundFolds.push(fold);
+ }
+ }
+ return foundFolds;
+ }
+
+ /**
+ * 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"
+ */
+ this.getFoldStringAt = function(row, column, trim, foldLine) {
+ var foldLine = foldLine || this.getFoldLine(row);
+ if (!foldLine)
+ return null;
+
+ var lastFold = {
+ end: { column: 0 }
+ };
+ // TODO: Refactor to use getNextFoldTo function.
+ for (var i = 0; i < foldLine.folds.length; i++) {
+ var fold = foldLine.folds[i];
+ var cmp = fold.range.compareEnd(row, column);
+ if (cmp == -1) {
+ var str = this
+ .getLine(fold.start.row)
+ .substring(lastFold.end.column, fold.start.column);
+ break;
+ }
+ else if (cmp == 0) {
+ return null;
+ }
+ lastFold = fold;
+ }
+ if (!str)
+ str = this.getLine(fold.start.row).substring(lastFold.end.column);
+
+ if (trim == -1)
+ return str.substring(0, column - lastFold.end.column);
+ else if (trim == 1)
+ return str.substring(column - lastFold.end.column)
+ else
+ return str;
+ }
+
+ this.getFoldLine = function(docRow, startFoldLine) {
+ var foldData = this.$foldData;
+ var i = 0;
+ if (startFoldLine)
+ i = foldData.indexOf(startFoldLine);
+ if (i == -1)
+ i = 0;
+ for (i; i < foldData.length; i++) {
+ var foldLine = foldData[i];
+ if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
+ return foldLine;
+ } else if (foldLine.end.row > docRow) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ // returns the fold which starts after or contains docRow
+ this.getNextFold = function(docRow, startFoldLine) {
+ var foldData = this.$foldData, ans;
+ var i = 0;
+ if (startFoldLine)
+ i = foldData.indexOf(startFoldLine);
+ if (i == -1)
+ i = 0;
+ for (i; i < foldData.length; i++) {
+ var foldLine = foldData[i];
+ if (foldLine.end.row >= docRow) {
+ return foldLine;
+ }
+ }
+ return null;
+ }
+
+ this.getFoldedRowCount = function(first, last) {
+ var foldData = this.$foldData, rowCount = last-first+1;
+ for (var i = 0; i < foldData.length; i++) {
+ var foldLine = foldData[i],
+ end = foldLine.end.row,
+ start = foldLine.start.row;
+ if (end >= last) {
+ if(start < last) {
+ if(start >= first)
+ rowCount -= last-start;
+ else
+ rowCount = 0;//in one fold
+ }
+ break;
+ } else if(end >= first){
+ if (start >= first) //fold inside range
+ rowCount -= end-start;
+ else
+ rowCount -= end-first+1;
+ }
+ }
+ return rowCount;
+ }
+
+ this.$addFoldLine = function(foldLine) {
+ this.$foldData.push(foldLine);
+ this.$foldData.sort(function(a, b) {
+ return a.start.row - b.start.row;
+ });
+ return foldLine;
+ }
+
+ /**
+ * Adds a new fold.
+ *
+ * @returns
+ * The new created Fold object or an existing fold object in case the
+ * passed in range fits an existing fold exactly.
+ */
+ this.addFold = function(placeholder, range) {
+ var foldData = this.$foldData;
+ var added = false;
+
+ if (placeholder instanceof Fold)
+ var fold = placeholder;
+ else
+ fold = new Fold(range, placeholder);
+
+ var startRow = fold.start.row;
+ var startColumn = fold.start.column;
+ var endRow = fold.end.row;
+ var endColumn = fold.end.column;
+
+ // --- Some checking ---
+ if (fold.placeholder.length < 2)
+ throw "Placeholder has to be at least 2 characters";
+
+ if (startRow == endRow && endColumn - startColumn < 2)
+ throw "The range has to be at least 2 characters width";
+
+ var existingFold = this.getFoldAt(startRow, startColumn, 1);
+ if (
+ existingFold
+ && existingFold.range.isEnd(endRow, endColumn)
+ && existingFold.range.isStart(startRow, startColumn)
+ ) {
+ return fold;
+ }
+
+ existingFold = this.getFoldAt(startRow, startColumn, 1);
+ if (existingFold && !existingFold.range.isStart(startRow, startColumn))
+ throw "A fold can't start inside of an already existing fold";
+
+ existingFold = this.getFoldAt(endRow, endColumn, -1);
+ if (existingFold && !existingFold.range.isEnd(endRow, endColumn))
+ throw "A fold can't end inside of an already existing fold";
+
+ if (endRow >= this.doc.getLength())
+ throw "End of fold is outside of the document.";
+
+ if (endColumn > this.getLine(endRow).length || startColumn > this.getLine(startRow).length)
+ throw "End of fold is outside of the document.";
+
+ // Check if there are folds in the range we create the new fold for.
+ var folds = this.getFoldsInRange(fold.range);
+ if (folds.length > 0) {
+ // Remove the folds from fold data.
+ this.removeFolds(folds);
+ // Add the removed folds as subfolds on the new fold.
+ fold.subFolds = folds;
+ }
+
+ for (var i = 0; i < foldData.length; i++) {
+ var foldLine = foldData[i];
+ if (endRow == foldLine.start.row) {
+ foldLine.addFold(fold);
+ added = true;
+ break;
+ }
+ else if (startRow == foldLine.end.row) {
+ foldLine.addFold(fold);
+ added = true;
+ if (!fold.sameRow) {
+ // Check if we might have to merge two FoldLines.
+ foldLineNext = foldData[i + 1];
+ if (foldLineNext && foldLineNext.start.row == endRow) {
+ // We need to merge!
+ foldLine.merge(foldLineNext);
+ break;
+ }
+ }
+ break;
+ }
+ else if (endRow <= foldLine.start.row) {
+ break;
+ }
+ }
+
+ if (!added)
+ foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
+
+ if (this.$useWrapMode)
+ this.$updateWrapData(foldLine.start.row, foldLine.start.row);
+
+ // Notify that fold data has changed.
+ this.$modified = true;
+ this._dispatchEvent("changeFold", { data: fold });
+
+ return fold;
+ };
+
+ this.addFolds = function(folds) {
+ folds.forEach(function(fold) {
+ this.addFold(fold);
+ }, this);
+ };
+
+ this.removeFold = function(fold) {
+ var foldLine = fold.foldLine;
+ var startRow = foldLine.start.row;
+ var endRow = foldLine.end.row;
+
+ var foldLines = this.$foldData,
+ folds = foldLine.folds;
+ // Simple case where there is only one fold in the FoldLine such that
+ // the entire fold line can get removed directly.
+ if (folds.length == 1) {
+ foldLines.splice(foldLines.indexOf(foldLine), 1);
+ } else
+ // If the fold is the last fold of the foldLine, just remove it.
+ if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {
+ folds.pop();
+ foldLine.end.row = folds[folds.length - 1].end.row;
+ foldLine.end.column = folds[folds.length - 1].end.column;
+ } else
+ // If the fold is the first fold of the foldLine, just remove it.
+ if (foldLine.range.isStart(fold.start.row, fold.start.column)) {
+ folds.shift();
+ foldLine.start.row = folds[0].start.row;
+ foldLine.start.column = folds[0].start.column;
+ } else
+ // We know there are more then 2 folds and the fold is not at the edge.
+ // This means, the fold is somewhere in between.
+ //
+ // If the fold is in one row, we just can remove it.
+ if (fold.sameRow) {
+ folds.splice(folds.indexOf(fold), 1);
+ } else
+ // The fold goes over more then one row. This means remvoing this fold
+ // will cause the fold line to get splitted up.
+ {
+ var newFoldLine = foldLine.split(fold.start.row, fold.start.column);
+ newFoldLine.folds.shift();
+ foldLine.start.row = folds[0].start.row;
+ foldLine.start.column = folds[0].start.column;
+ this.$addFoldLine(newFoldLine);
+ }
+
+ if (this.$useWrapMode) {
+ this.$updateWrapData(startRow, endRow);
+ }
+
+ // Notify that fold data has changed.
+ this.$modified = true;
+ this._dispatchEvent("changeFold", { data: fold });
+ }
+
+ this.removeFolds = function(folds) {
+ // We need to clone the folds array passed in as it might be the folds
+ // array of a fold line and as we call this.removeFold(fold), folds
+ // are removed from folds and changes the current index.
+ var cloneFolds = [];
+ for (var i = 0; i < folds.length; i++) {
+ cloneFolds.push(folds[i]);
+ }
+
+ cloneFolds.forEach(function(fold) {
+ this.removeFold(fold);
+ }, this);
+ this.$modified = true;
+ }
+
+ this.expandFold = function(fold) {
+ this.removeFold(fold);
+ fold.subFolds.forEach(function(fold) {
+ this.addFold(fold);
+ }, this);
+ fold.subFolds = [];
+ }
+
+ this.expandFolds = function(folds) {
+ folds.forEach(function(fold) {
+ this.expandFold(fold);
+ }, this);
+ }
+
+ /**
+ * 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.
+ **/
+ this.isRowFolded = function(docRow, startFoldRow) {
+ return !!this.getFoldLine(docRow, startFoldRow);
+ };
+
+ this.getRowFoldEnd = function(docRow, startFoldRow) {
+ var foldLine = this.getFoldLine(docRow, startFoldRow);
+ return (foldLine
+ ? foldLine.end.row
+ : docRow)
+ };
+
+ this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
+ if (startRow == null) {
+ startRow = foldLine.start.row;
+ startColumn = 0;
+ }
+
+ if (endRow == null) {
+ endRow = foldLine.end.row;
+ endColumn = this.getLine(endRow).length;
+ }
+
+ // Build the textline using the FoldLine walker.
+ var line = "";
+ var doc = this.doc;
+ var textLine = "";
+
+ foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
+ if (row < startRow) {
+ return;
+ } else if (row == startRow) {
+ if (column < startColumn) {
+ return;
+ }
+ lastColumn = Math.max(startColumn, lastColumn);
+ }
+ if (placeholder) {
+ textLine += placeholder;
+ } else {
+ textLine += doc.getLine(row).substring(lastColumn, column);
+ }
+ }.bind(this), endRow, endColumn);
+ return textLine;
+ };
+
+ this.getDisplayLine = function(row, endColumn, startRow, startColumn) {
+ var foldLine = this.getFoldLine(row);
+
+ if (!foldLine) {
+ var line;
+ line = this.doc.getLine(row);
+ return line.substring(startColumn || 0, endColumn || line.length);
+ } else {
+ return this.getFoldDisplayLine(
+ foldLine, row, endColumn, startRow, startColumn);
+ }
+ };
+
+ this.$cloneFoldData = function() {
+ var foldData = this.$foldData;
+ var fd = [];
+ fd = this.$foldData.map(function(foldLine) {
+ var folds = foldLine.folds.map(function(fold) {
+ return fold.clone();
+ });
+ return new FoldLine(fd, folds);
+ });
+
+ return fd;
+ };
+}
+
+exports.Folding = Folding;
+
+});
\ No newline at end of file
diff --git a/ace/editor.js b/ace/editor.js
new file mode 100644
index 00000000..437a4da4
--- /dev/null
+++ b/ace/editor.js
@@ -0,0 +1,909 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Irakli Gozalishvili (http://jeditoolkit.com)
+ * Julian Viereck
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+require("ace/lib/fixoldbrowsers");
+
+var oop = require("ace/lib/oop");
+var event = require("ace/lib/event");
+var lang = require("ace/lib/lang");
+var useragent = require("ace/lib/useragent");
+var TextInput = require("ace/keyboard/textinput").TextInput;
+var MouseHandler = require("ace/mouse_handler").MouseHandler;
+//var TouchHandler = require("ace/touch_handler").TouchHandler;
+var KeyBinding = require("ace/keyboard/keybinding").KeyBinding;
+var Buffer = require("ace/model/buffer").Buffer;
+var Window = require("ace/model/window").Window;
+var WindowController = require("ace/window_controller").WindowController;
+var Search = require("ace/search").Search;
+var Range = require("ace/range").Range;
+var EventEmitter = require("ace/lib/event_emitter").EventEmitter;
+var CommandManager = require("ace/commands/command_manager").CommandManager;
+var defaultCommands = require("ace/commands/default_commands").commands;
+
+var Editor = function(windowView, buffer) {
+ var container = windowView.getContainerElement();
+ this.container = container;
+ this.renderer = windowView;
+
+ this.textInput = new TextInput(windowView.getTextAreaContainer(), this);
+ this.keyBinding = new KeyBinding(this);
+
+ // TODO detect touch event support
+ if (useragent.isIPad) {
+ //this.$mouseHandler = new TouchHandler(this);
+ } else {
+ this.$mouseHandler = new MouseHandler(this);
+ }
+
+ this.windowModel = this.renderer.model;
+ this.windowModel.search = new Search().set({
+ wrap: true
+ });
+ this.windowController = new WindowController(this.windowModel, this.renderer);
+
+ this.commands = new CommandManager(defaultCommands);
+ this.setSession(buffer || new Buffer(""));
+};
+
+(function(){
+
+ oop.implement(this, EventEmitter);
+
+ this.$forwardEvents = {
+ gutterclick: 1,
+ gutterdblclick: 1
+ };
+
+ this.$originalAddEventListener = this.addEventListener;
+ this.$originalRemoveEventListener = this.removeEventListener;
+
+ this.addEventListener = function(eventName, callback) {
+ if (this.$forwardEvents[eventName]) {
+ return this.renderer.addEventListener(eventName, callback);
+ } else {
+ return this.$originalAddEventListener(eventName, callback);
+ }
+ };
+
+ this.removeEventListener = function(eventName, callback) {
+ if (this.$forwardEvents[eventName]) {
+ return this.renderer.removeEventListener(eventName, callback);
+ } else {
+ return this.$originalRemoveEventListener(eventName, callback);
+ }
+ };
+
+ this.setKeyboardHandler = function(keyboardHandler) {
+ this.keyBinding.setKeyboardHandler(keyboardHandler);
+ };
+
+ this.getKeyboardHandler = function() {
+ return this.keyBinding.getKeyboardHandler();
+ };
+
+ // TODO refactor
+ // remove
+ this.setSession = function(session) {
+ if (this.session == session)
+ return;
+
+ this.windowModel.setBuffer(session);
+ this.session = session;
+ this.selection = session.getSelection();
+ };
+
+ this.getSession = function() {
+ return this.session;
+ };
+
+ this.getSelection = function() {
+ return this.selection;
+ };
+
+ this.resize = function() {
+ //this.renderer.onResize();
+ this.windowController.resize();
+ };
+
+ this.setTheme = function(theme) {
+ this.windowModel.setTheme(theme);
+ };
+
+ this.getTheme = function() {
+ return this.windowModel.getTheme();
+ };
+
+ this.setStyle = function(style) {
+ this.renderer.setStyle(style);
+ };
+
+ this.unsetStyle = function(style) {
+ this.renderer.unsetStyle(style);
+ };
+
+ this.setFontSize = function(size) {
+ this.container.style.fontSize = size;
+ };
+
+ this.focus = function() {
+ // Safari needs the timeout
+ // iOS and Firefox need it called immediately
+ // to be on the save side we do both
+ var _self = this;
+ setTimeout(function() {
+ _self.textInput.focus();
+ });
+ this.textInput.focus();
+ };
+
+ this.isFocused = function() {
+ return this.textInput.isFocused();
+ };
+
+ this.blur = function() {
+ this.textInput.blur();
+ };
+
+ this.onFocus = function() {
+ this.renderer.showCursor();
+ this.renderer.visualizeFocus();
+ this._dispatchEvent("focus");
+ };
+
+ this.onBlur = function() {
+ this.renderer.hideCursor();
+ this.renderer.visualizeBlur();
+ this._dispatchEvent("blur");
+ };
+
+ this.getCopyText = function() {
+ var text = "";
+ if (!this.selection.isEmpty())
+ text = this.session.getTextRange(this.getSelectionRange());
+
+ this._emit("copy", text);
+ return text;
+ };
+
+ this.onCut = function() {
+ if (this.$readOnly)
+ return;
+
+ var range = this.getSelectionRange();
+ this._emit("cut", range);
+
+ if (!this.selection.isEmpty()) {
+ this.session.remove(range)
+ this.clearSelection();
+ }
+ };
+
+ this.insert = function(text) {
+ if (this.$readOnly)
+ return;
+
+ var session = this.session;
+ var mode = session.getMode();
+
+ var cursor = this.getCursorPosition();
+
+ if (this.getBehavioursEnabled()) {
+ // Get a transform if the current mode wants one.
+ var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
+ if (transform)
+ text = transform.text;
+ }
+
+ text = text.replace("\t", this.session.getTabString());
+
+ // remove selected text
+ if (!this.selection.isEmpty()) {
+ var cursor = this.session.remove(this.getSelectionRange());
+ this.clearSelection();
+ }
+ else if (this.session.getOverwrite()) {
+ var range = new Range.fromPoints(cursor, cursor);
+ range.end.column += text.length;
+ this.session.remove(range);
+ }
+
+ this.clearSelection();
+
+ var start = cursor.column;
+ var lineState = session.getState(cursor.row);
+ var shouldOutdent = mode.checkOutdent(lineState, session.getLine(cursor.row), text);
+ var line = session.getLine(cursor.row);
+ var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
+ var end = 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]));
+ }
+ }
+
+ var lineState = session.getState(cursor.row);
+
+ // TODO disabled multiline auto indent
+ // possibly doing the indent before inserting the text
+ // if (cursor.row !== end.row) {
+ if (session.getDocument().isNewLine(text)) {
+ this.moveCursorTo(cursor.row+1, 0);
+
+ var size = session.getTabSize();
+ var minIndent = Number.MAX_VALUE;
+
+ for (var row = cursor.row + 1; row <= end.row; ++row) {
+ var indent = 0;
+
+ line = session.getLine(row);
+ for (var i = 0; i < line.length; ++i)
+ if (line.charAt(i) == '\t')
+ indent += size;
+ else if (line.charAt(i) == ' ')
+ indent += 1;
+ else
+ break;
+ if (/[^\s]/.test(line))
+ minIndent = Math.min(indent, minIndent);
+ }
+
+ for (var row = cursor.row + 1; row <= end.row; ++row) {
+ var outdent = minIndent;
+
+ line = session.getLine(row);
+ for (var i = 0; i < line.length && outdent > 0; ++i)
+ if (line.charAt(i) == '\t')
+ outdent -= size;
+ else if (line.charAt(i) == ' ')
+ outdent -= 1;
+ session.remove(new Range(row, 0, row, i));
+ }
+ session.indentRows(cursor.row + 1, end.row, lineIndent);
+ } else {
+ if (shouldOutdent) {
+ mode.autoOutdent(lineState, session, cursor.row);
+ }
+ }
+ };
+
+ this.onTextInput = function(text) {
+ // In case we got only one character, then
+ // handel it as a command key stroke.
+ if (text.length == 1) {
+ // Note: The `null` as `keyCode` is important here, as there are
+ // some checks in the code for `keyCode == 0` meaning the text comes
+ // from the keyBinding.onTextInput code path.
+ var handled = this.keyBinding.onCommandKey({}, 0, null, text);
+
+ // Check if the text was handled. If not, then handled it as "normal"
+ // text and insert it to the editor directly. This shouldn't be done
+ // using the this.keyBinding.onTextInput(text) function, as it would
+ // make the `text` get sent to the keyboardHandler twice, which might
+ // turn out to be a bad thing in case there is a custome keyboard
+ // handler like the StateHandler.
+ if (!handled) {
+ this.insert(text);
+ }
+ } else {
+ this.keyBinding.onTextInput(text);
+ }
+ };
+
+ this.onPaste = function(text) {
+ this._emit("paste", text);
+ this.keyBinding.onTextInput(text);
+ };
+
+ this.onCommandKey = function(e, hashId, keyCode) {
+ this.keyBinding.onCommandKey(e, hashId, keyCode);
+ };
+
+ this.setOverwrite = function(overwrite) {
+ this.session.setOverwrite(overwrite);
+ };
+
+ this.getOverwrite = function() {
+ return this.session.getOverwrite();
+ };
+
+ this.toggleOverwrite = function() {
+ this.session.toggleOverwrite();
+ };
+
+ this.setScrollSpeed = function(speed) {
+ this.$mouseHandler.setScrollSpeed(speed);
+ };
+
+ this.getScrollSpeed = function() {
+ return this.$mouseHandler.getScrollSpeed()
+ };
+
+ this.setSelectionStyle = function(style) {
+ this.windowModel.setSelectionStyle(style);
+ };
+
+ this.getSelectionStyle = function() {
+ return this.windowModel.getSelectionStyle();
+ };
+
+ this.setHighlightActiveLine = function(shouldHighlight) {
+ this.windowModel.setHighlightActiveLine(shouldHighlight);
+ };
+
+ this.getHighlightActiveLine = function() {
+ return this.windowModel.getHighlightActiveLine();
+ };
+
+ this.setHighlightSelectedWord = function(shouldHighlight) {
+ this.windowModel.setHighlightSelectedWord(shouldHighlight);
+ };
+
+ this.getHighlightSelectedWord = function() {
+ return this.windowModel.getHighlightSelectedWord();
+ };
+
+ this.setShowInvisibles = function(showInvisibles) {
+ this.windowModel.setShowInvisibles(showInvisibles);
+ };
+
+ this.getShowInvisibles = function() {
+ return this.windowModel.getShowInvisibles();
+ };
+
+ this.setShowPrintMargin = function(showPrintMargin) {
+ this.windowModel.setShowPrintMargin(showPrintMargin);
+ };
+
+ this.getShowPrintMargin = function() {
+ return this.windowModel.getShowPrintMargin();
+ };
+
+ this.setPrintMarginColumn = function(showPrintMargin) {
+ this.windowModel.setPrintMarginColumn(showPrintMargin);
+ };
+
+ this.getPrintMarginColumn = function() {
+ return this.windowModel.getPrintMarginColumn();
+ };
+
+ this.setShowGutter = function(showGutter) {
+ this.windowModel.setShowGutter(showGutter);
+ };
+
+ this.getShowGutter = function() {
+ return this.windowModel.getShowGutter();
+ };
+
+ this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
+ this.windowModel.setHScrollBarAlwaysVisible(alwaysVisible);
+ };
+
+ this.getHScrollBarAlwaysVisible = function() {
+ return this.windowModel.getHScrollBarAlwaysVisible();
+ };
+
+ this.$readOnly = false;
+ this.setReadOnly = function(readOnly) {
+ this.$readOnly = readOnly;
+ };
+
+ this.getReadOnly = function() {
+ return this.$readOnly;
+ };
+
+ this.$modeBehaviours = true;
+ this.setBehavioursEnabled = function (enabled) {
+ this.$modeBehaviours = enabled;
+ }
+
+ this.getBehavioursEnabled = function () {
+ return this.$modeBehaviours;
+ }
+
+ this.removeRight = function() {
+ if (this.$readOnly)
+ return;
+
+ if (this.selection.isEmpty()) {
+ this.selection.selectRight();
+ }
+ this.session.remove(this.getSelectionRange())
+ this.clearSelection();
+ };
+
+ this.removeLeft = function() {
+ if (this.$readOnly)
+ return;
+
+ if (this.selection.isEmpty())
+ this.selection.selectLeft();
+
+ 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 (new_range !== false) {
+ range = new_range;
+ }
+ }
+
+ this.session.remove(range);
+ this.clearSelection();
+ };
+
+ this.removeWordRight = function() {
+ if (this.$readOnly)
+ return;
+
+ if (this.selection.isEmpty())
+ this.selection.selectWordRight();
+
+ this.session.remove(this.getSelectionRange());
+ this.clearSelection();
+ };
+
+ this.removeWordLeft = function() {
+ if (this.$readOnly)
+ return;
+
+ if (this.selection.isEmpty())
+ this.selection.selectWordLeft();
+
+ this.session.remove(this.getSelectionRange());
+ this.clearSelection();
+ };
+
+ this.removeToLineStart = function() {
+ if (this.$readOnly)
+ return;
+
+ if (this.selection.isEmpty())
+ this.selection.selectLineStart();
+
+ this.session.remove(this.getSelectionRange());
+ this.clearSelection();
+ };
+
+ this.removeToLineEnd = function() {
+ if (this.$readOnly)
+ return;
+
+ 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();
+ };
+
+ this.splitLine = function() {
+ if (this.$readOnly)
+ return;
+
+ if (!this.selection.isEmpty()) {
+ this.session.remove(this.getSelectionRange());
+ this.clearSelection();
+ }
+
+ var cursor = this.getCursorPosition();
+ this.insert("\n");
+ this.moveCursorToPosition(cursor);
+ };
+
+ this.transposeLetters = function() {
+ if (this.$readOnly)
+ return;
+
+ if (!this.selection.isEmpty()) {
+ return;
+ }
+
+ var cursor = this.getCursorPosition();
+ var column = cursor.column;
+ if (column == 0)
+ return;
+
+ var line = this.session.getLine(cursor.row);
+ if (column < line.length) {
+ var swap = line.charAt(column) + line.charAt(column-1);
+ var range = new Range(cursor.row, column-1, cursor.row, column+1)
+ }
+ else {
+ var swap = line.charAt(column-1) + line.charAt(column-2);
+ var range = new Range(cursor.row, column-2, cursor.row, column)
+ }
+ this.session.replace(range, swap);
+ };
+
+ this.indent = function() {
+ if (this.$readOnly)
+ return;
+
+ var session = this.session;
+ var range = this.getSelectionRange();
+
+ if (range.start.row < range.end.row || range.start.column < range.end.column) {
+ var rows = this.$getSelectedRows();
+ session.indentRows(rows.first, rows.last, "\t");
+ } else {
+ var indentString;
+
+ if (this.session.getUseSoftTabs()) {
+ var size = session.getTabSize(),
+ position = this.getCursorPosition(),
+ column = session.documentToScreenColumn(position.row, position.column),
+ count = (size - column % size);
+
+ indentString = lang.stringRepeat(" ", count);
+ } else
+ indentString = "\t";
+ return this.onTextInput(indentString);
+ }
+ };
+
+ this.blockOutdent = function() {
+ if (this.$readOnly)
+ return;
+
+ var selection = this.session.getSelection();
+ this.session.outdentRows(selection.getRange());
+ };
+
+ this.toggleCommentLines = function() {
+ if (this.$readOnly)
+ return;
+
+ var state = this.session.getState(this.getCursorPosition().row);
+ var rows = this.$getSelectedRows()
+ this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
+ };
+
+ this.removeLines = function() {
+ if (this.$readOnly)
+ return;
+
+ var rows = this.$getSelectedRows();
+ if (rows.last == 0 || rows.last+1 < this.session.getLength())
+ var range = new Range(rows.first, 0, rows.last+1, 0)
+ else
+ var range = new Range(
+ rows.first-1, this.session.getLine(rows.first-1).length,
+ rows.last, this.session.getLine(rows.last).length
+ );
+ this.session.remove(range);
+ this.clearSelection();
+ };
+
+ this.moveLinesDown = function() {
+ if (this.$readOnly)
+ return;
+
+ this.$moveLines(function(firstRow, lastRow) {
+ return this.session.moveLinesDown(firstRow, lastRow);
+ });
+ };
+
+ this.moveLinesUp = function() {
+ if (this.$readOnly)
+ return;
+
+ this.$moveLines(function(firstRow, lastRow) {
+ return this.session.moveLinesUp(firstRow, lastRow);
+ });
+ };
+
+ this.moveText = function(range, toPosition) {
+ if (this.$readOnly)
+ return null;
+
+ return this.session.moveText(range, toPosition);
+ };
+
+ this.copyLinesUp = function() {
+ if (this.$readOnly)
+ return;
+
+ this.$moveLines(function(firstRow, lastRow) {
+ this.session.duplicateLines(firstRow, lastRow);
+ return 0;
+ });
+ };
+
+ this.copyLinesDown = function() {
+ if (this.$readOnly)
+ return;
+
+ this.$moveLines(function(firstRow, lastRow) {
+ return this.session.duplicateLines(firstRow, lastRow);
+ });
+ };
+
+
+ this.$moveLines = function(mover) {
+ var rows = this.$getSelectedRows();
+
+ var linesMoved = mover.call(this, rows.first, rows.last);
+
+ var selection = this.selection;
+ selection.setSelectionAnchor(rows.last+linesMoved+1, 0);
+ selection.$moveSelection(function() {
+ selection.moveCursorTo(rows.first+linesMoved, 0);
+ });
+ };
+
+ this.$getSelectedRows = function() {
+ var range = this.getSelectionRange().collapseRows();
+
+ return {
+ first: range.start.row,
+ last: range.end.row
+ };
+ };
+
+ this.onCompositionStart = function(text) {
+ this.renderer.showComposition(this.getCursorPosition());
+ };
+
+ this.onCompositionUpdate = function(text) {
+ this.renderer.setCompositionText(text);
+ };
+
+ this.onCompositionEnd = function() {
+ this.renderer.hideComposition();
+ };
+
+ this.getFirstVisibleRow = function() {
+ return this.windowModel.getFirstVisibleRow();
+ };
+
+ this.getLastVisibleRow = function() {
+ return this.windowModel.getLastVisibleRow();
+ };
+
+ this.isRowVisible = function(row) {
+ return this.windowModel.isRowVisible(row);
+ };
+
+ this.$getVisibleRowCount = function() {
+ return this.windowModel.getVisibleRowCount();
+ };
+
+ this.$getPageDownRow = function() {
+ return this.windowModel.getPageDownRow();
+ };
+
+ this.$getPageUpRow = function() {
+ return this.windowModel.getPageUpRow();
+ };
+
+ this.selectPageDown = function() {
+ var row = this.$getPageDownRow() + Math.floor(this.$getVisibleRowCount() / 2);
+
+ this.scrollPageDown();
+
+ var selection = this.getSelection();
+ var leadScreenPos = this.session.documentToScreenPosition(selection.getSelectionLead());
+ var dest = this.session.screenToDocumentPosition(row, leadScreenPos.column);
+ selection.selectTo(dest.row, dest.column);
+ };
+
+ this.selectPageUp = function() {
+ var visibleRows = this.windowModel.getScrollTopRow() - this.windowModel.getScrollBottomRow();
+ var row = this.$getPageUpRow() + Math.round(visibleRows / 2);
+
+ this.scrollPageUp();
+
+ var selection = this.getSelection();
+ var leadScreenPos = this.session.documentToScreenPosition(selection.getSelectionLead());
+ var dest = this.session.screenToDocumentPosition(row, leadScreenPos.column);
+ selection.selectTo(dest.row, dest.column);
+ };
+
+ this.gotoPageDown = function() {
+ var row = this.$getPageDownRow();
+ var column = this.getCursorPositionScreen().column;
+
+ this.scrollToRow(row);
+ this.getSelection().moveCursorToScreen(row, column);
+ };
+
+ this.gotoPageUp = function() {
+ var row = this.$getPageUpRow();
+ var column = this.getCursorPositionScreen().column;
+
+ this.scrollToRow(row);
+ this.getSelection().moveCursorToScreen(row, column);
+ };
+
+ this.scrollPageDown = function() {
+ this.scrollToRow(this.$getPageDownRow());
+ };
+
+ this.scrollPageUp = function() {
+ this.windowModel.scrollToRow(this.$getPageUpRow());
+ };
+
+ this.scrollToRow = function(row) {
+ this.windowModel.scrollToRow(row);
+ };
+
+ this.scrollToLine = function(line, center) {
+ this.windowModel.scrollToLine(line, center);
+ };
+
+ this.centerSelection = function() {
+ this.windowModel.centerSelection();
+ };
+
+ this.getCursorPosition = function() {
+ return this.windowModel.getCursorPosition();
+ };
+
+ this.getCursorPositionScreen = function() {
+ return this.windowModel.getCursorPositionScreen();
+ };
+
+ this.getSelectionRange = function() {
+ return this.windowModel.getSelectionRange();
+ };
+
+ this.selectAll = function() {
+ this.windowModel.selectAll();
+ };
+
+ this.clearSelection = function() {
+ this.windowModel.clearSelection();
+ };
+
+ this.moveCursorTo = function(row, column) {
+ this.windowModel.moveCursorTo(row, column);
+ };
+
+ this.moveCursorToPosition = function(pos) {
+ this.windowModel.moveCursorToPosition(pos);
+ };
+
+
+ this.gotoLine = function(lineNumber, column) {
+ this.windowModel.gotoLine(lineNumber, column);
+ };
+
+ this.navigateTo = function(row, column) {
+ this.windowModel.navigateTo(row, column);
+ };
+
+ this.navigateUp = function(times) {
+ this.windowModel.navigateUp(times);
+ };
+
+ this.navigateDown = function(times) {
+ this.windowModel.navigateDown(times);
+ };
+
+ this.navigateLeft = function(times) {
+ this.windowModel.navigateLeft(times);
+ };
+
+ this.navigateRight = function(times) {
+ this.windowModel.navigateRight(times);
+ };
+
+ this.navigateLineStart = function() {
+ this.windowModel.navigateLineStart()
+ };
+
+ this.navigateLineEnd = function() {
+ this.windowModel.navigateLineEnd();
+ };
+
+ this.navigateFileEnd = function() {
+ this.windowModel.navigateFileEnd();
+ };
+
+ this.navigateFileStart = function() {
+ this.windowModel.navigateFileStart();
+ };
+
+ this.navigateWordRight = function() {
+ this.windowModel.navigateWordRight();
+ };
+
+ this.navigateWordLeft = function() {
+ this.windowModel.navigateWordLeft();
+ };
+
+ this.replace = function(replacement, options) {
+ this.windowModel.replace(replace, options);
+ };
+
+ this.replaceAll = function(replacement, options) {
+ this.windowModel.replaceAll(replaceAll, options);
+ };
+
+ this.getLastSearchOptions = function() {
+ return this.windowModel.getLastSearchOptions();
+ };
+
+ this.find = function(needle, options) {
+ this.windowModel.find(needle, options);
+ };
+
+ this.findNext = function(options) {
+ this.windowModel.findNext(options);
+ };
+
+ this.findPrevious = function(options) {
+ this.windowModel.findPrevious(options);
+ };
+
+ this.undo = function() {
+ this.session.getUndoManager().undo();
+ };
+
+ this.redo = function() {
+ this.session.getUndoManager().redo();
+ };
+
+ this.destroy = function() {
+ this.renderer.destroy();
+ }
+
+}).call(Editor.prototype);
+
+
+exports.Editor = Editor;
+});
diff --git a/lib/ace/editor_text_edit_test.js b/ace/editor_text_edit_test.js
similarity index 56%
rename from lib/ace/editor_text_edit_test.js
rename to ace/editor_text_edit_test.js
index 77ec34ed..f74884eb 100644
--- a/lib/ace/editor_text_edit_test.js
+++ b/ace/editor_text_edit_test.js
@@ -1,53 +1,58 @@
/* ***** BEGIN LICENSE BLOCK *****
- * Distributed under the BSD license:
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
- * 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.
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
if (typeof process !== "undefined") {
- require("amd-loader");
- require("./test/mockdom");
+ require("../support/paths");
+ require("ace/test/mockdom");
}
define(function(require, exports, module) {
-"use strict";
-var EditSession = require("./edit_session").EditSession;
-var Editor = require("./editor").Editor;
-var JavaScriptMode = require("./mode/javascript").Mode;
-var UndoManager = require("./undomanager").UndoManager;
-var MockRenderer = require("./test/mockrenderer").MockRenderer;
-var assert = require("./test/assertions");
-var whitespace = require("./ext/whitespace");
+var Buffer = require("ace/model/buffer").Buffer;
+var Editor = require("ace/editor").Editor;
+var JavaScriptMode = require("ace/mode/javascript").Mode;
+var UndoManager = require("ace/undomanager").UndoManager;
+var WindowViewMock = require("ace/view/window_view_mock").WindowViewMock;
+var assert = require("ace/test/assertions");
module.exports = {
"test: delete line from the middle" : function() {
- var session = new EditSession(["a", "b", "c", "d"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(["a", "b", "c", "d"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 1);
editor.removeLines();
@@ -72,8 +77,8 @@ module.exports = {
},
"test: delete multiple selected lines" : function() {
- var session = new EditSession(["a", "b", "c", "d"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(["a", "b", "c", "d"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
@@ -84,8 +89,8 @@ module.exports = {
},
"test: delete first line" : function() {
- var session = new EditSession(["a", "b", "c"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(["a", "b", "c"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.removeLines();
@@ -94,8 +99,8 @@ module.exports = {
},
"test: delete last should also delete the new line of the previous line" : function() {
- var session = new EditSession(["a", "b", "c", ""].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(["a", "b", "c", ""].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(3, 0);
@@ -109,8 +114,8 @@ module.exports = {
},
"test: indent block" : function() {
- var session = new EditSession(["a12345", "b12345", "c12345"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(["a12345", "b12345", "c12345"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 3);
editor.getSelection().selectDown();
@@ -127,8 +132,8 @@ module.exports = {
},
"test: indent selected lines" : function() {
- var session = new EditSession(["a12345", "b12345", "c12345"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(["a12345", "b12345", "c12345"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 0);
editor.getSelection().selectDown();
@@ -138,17 +143,17 @@ module.exports = {
},
"test: no auto indent if cursor is before the {" : function() {
- var session = new EditSession("{", new JavaScriptMode());
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer("{", new JavaScriptMode());
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(0, 0);
editor.onTextInput("\n");
assert.equal(["", "{"].join("\n"), session.toString());
},
-
+
"test: outdent block" : function() {
- var session = new EditSession([" a12345", " b12345", " c12345"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer([" a12345", " b12345", " c12345"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(0, 5);
editor.getSelection().selectDown();
@@ -172,8 +177,8 @@ module.exports = {
},
"test: outent without a selection should update cursor" : function() {
- var session = new EditSession(" 12");
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(" 12");
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(0, 3);
editor.blockOutdent(" ");
@@ -183,25 +188,23 @@ module.exports = {
},
"test: comment lines should perserve selection" : function() {
- var session = new EditSession([" abc", "cde"].join("\n"), new JavaScriptMode());
- var editor = new Editor(new MockRenderer(), session);
- whitespace.detectIndentation(session);
-
+ var session = new Buffer([" abc", "cde"].join("\n"), new JavaScriptMode());
+ var editor = new Editor(new WindowViewMock(), session);
+
editor.moveCursorTo(0, 2);
editor.getSelection().selectDown();
editor.toggleCommentLines();
- assert.equal(["// abc", "// cde"].join("\n"), session.toString());
+ assert.equal(["// abc", "//cde"].join("\n"), session.toString());
var selection = editor.getSelectionRange();
- assert.position(selection.start, 0, 5);
- assert.position(selection.end, 1, 5);
+ assert.position(selection.start, 0, 4);
+ assert.position(selection.end, 1, 4);
},
"test: uncomment lines should perserve selection" : function() {
- var session = new EditSession(["// abc", "//cde"].join("\n"), new JavaScriptMode());
- var editor = new Editor(new MockRenderer(), session);
- session.setTabSize(2);
+ var session = new Buffer(["// abc", "//cde"].join("\n"), new JavaScriptMode());
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(0, 1);
editor.getSelection().selectDown();
@@ -215,8 +218,8 @@ module.exports = {
},
"test: toggle comment lines twice should return the original text" : function() {
- var session = new EditSession([" abc", "cde", "fg"], new JavaScriptMode());
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer([" abc", "cde", "fg"], new JavaScriptMode());
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(0, 0);
editor.getSelection().selectDown();
@@ -231,94 +234,95 @@ module.exports = {
"test: comment lines - if the selection end is at the line start it should stay there": function() {
//select down
- var session = new EditSession(["abc", "cde"].join("\n"), new JavaScriptMode());
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(["abc", "cde"].join("\n"), new JavaScriptMode());
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(0, 0);
editor.getSelection().selectDown();
editor.toggleCommentLines();
- assert.range(editor.getSelectionRange(), 0, 3, 1, 0);
+ assert.range(editor.getSelectionRange(), 0, 2, 1, 0);
// select up
- var session = new EditSession(["abc", "cde"].join("\n"), new JavaScriptMode());
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer(["abc", "cde"].join("\n"), new JavaScriptMode());
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 0);
editor.getSelection().selectUp();
editor.toggleCommentLines();
- assert.range(editor.getSelectionRange(), 0, 3, 1, 0);
+ assert.range(editor.getSelectionRange(), 0, 2, 1, 0);
},
- "test: move lines down should keep selection on moved lines" : function() {
- var session = new EditSession(["11", "22", "33", "44"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ "test: move lines down should select moved lines" : function() {
+ var session = new Buffer(["11", "22", "33", "44"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(0, 1);
editor.getSelection().selectDown();
editor.moveLinesDown();
assert.equal(["33", "11", "22", "44"].join("\n"), session.toString());
- assert.position(editor.getCursorPosition(), 2, 1);
- assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);
- assert.position(editor.getSelection().getSelectionLead(), 2, 1);
+ assert.position(editor.getCursorPosition(), 1, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 1, 0);
editor.moveLinesDown();
assert.equal(["33", "44", "11", "22"].join("\n"), session.toString());
- assert.position(editor.getCursorPosition(), 3, 1);
- assert.position(editor.getSelection().getSelectionAnchor(), 2, 1);
- assert.position(editor.getSelection().getSelectionLead(), 3, 1);
+ assert.position(editor.getCursorPosition(), 2, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 2);
+ assert.position(editor.getSelection().getSelectionLead(), 2, 0);
// moving again should have no effect
editor.moveLinesDown();
assert.equal(["33", "44", "11", "22"].join("\n"), session.toString());
- assert.position(editor.getCursorPosition(), 3, 1);
- assert.position(editor.getSelection().getSelectionAnchor(), 2, 1);
- assert.position(editor.getSelection().getSelectionLead(), 3, 1);
+ assert.position(editor.getCursorPosition(), 2, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 2);
+ assert.position(editor.getSelection().getSelectionLead(), 2, 0);
},
- "test: move lines up should keep selection on moved lines" : function() {
- var session = new EditSession(["11", "22", "33", "44"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ "test: move lines up should select moved lines" : function() {
+ var session = new Buffer(["11", "22", "33", "44"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(2, 1);
editor.getSelection().selectDown();
editor.moveLinesUp();
assert.equal(session.toString(), ["11", "33", "44", "22"].join("\n"));
- assert.position(editor.getCursorPosition(), 2, 1);
- assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);
- assert.position(editor.getSelection().getSelectionLead(), 2, 1);
+ assert.position(editor.getCursorPosition(), 1, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 1, 0);
editor.moveLinesUp();
assert.equal(session.toString(), ["33", "44", "11", "22"].join("\n"));
- assert.position(editor.getCursorPosition(), 1, 1);
- assert.position(editor.getSelection().getSelectionAnchor(), 0, 1);
- assert.position(editor.getSelection().getSelectionLead(), 1, 1);
+ assert.position(editor.getCursorPosition(), 0, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 2, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 0, 0);
},
- "test: move line without active selection should not move cursor relative to the moved line" : function() {
- var session = new EditSession(["11", "22", "33", "44"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ "test: move line without active selection should move cursor to start of the moved line" : function()
+ {
+ var session = new Buffer(["11", "22", "33", "44"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 1);
editor.clearSelection();
editor.moveLinesDown();
assert.equal(["11", "33", "22", "44"].join("\n"), session.toString());
- assert.position(editor.getCursorPosition(), 2, 1);
+ assert.position(editor.getCursorPosition(), 2, 0);
editor.clearSelection();
editor.moveLinesUp();
assert.equal(["11", "22", "33", "44"].join("\n"), session.toString());
- assert.position(editor.getCursorPosition(), 1, 1);
+ assert.position(editor.getCursorPosition(), 1, 0);
},
- "test: copy lines down should keep selection" : function() {
- var session = new EditSession(["11", "22", "33", "44"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ "test: copy lines down should select lines and place cursor at the selection start" : function() {
+ var session = new Buffer(["11", "22", "33", "44"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
@@ -326,14 +330,14 @@ module.exports = {
editor.copyLinesDown();
assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString());
- assert.position(editor.getCursorPosition(), 4, 1);
- assert.position(editor.getSelection().getSelectionAnchor(), 3, 1);
- assert.position(editor.getSelection().getSelectionLead(), 4, 1);
+ assert.position(editor.getCursorPosition(), 3, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 5, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 3, 0);
},
- "test: copy lines up should keep selection" : function() {
- var session = new EditSession(["11", "22", "33", "44"].join("\n"));
- var editor = new Editor(new MockRenderer(), session);
+ "test: copy lines up should select lines and place cursor at the selection start" : function() {
+ var session = new Buffer(["11", "22", "33", "44"].join("\n"));
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
@@ -341,14 +345,14 @@ module.exports = {
editor.copyLinesUp();
assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString());
- assert.position(editor.getCursorPosition(), 2, 1);
- assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);
- assert.position(editor.getSelection().getSelectionLead(), 2, 1);
+ assert.position(editor.getCursorPosition(), 1, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 1, 0);
},
"test: input a tab with soft tab should convert it to spaces" : function() {
- var session = new EditSession("");
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer("");
+ var editor = new Editor(new WindowViewMock(), session);
session.setTabSize(2);
session.setUseSoftTabs(true);
@@ -362,8 +366,8 @@ module.exports = {
},
"test: input tab without soft tabs should keep the tab character" : function() {
- var session = new EditSession("");
- var editor = new Editor(new MockRenderer(), session);
+ var session = new Buffer("");
+ var editor = new Editor(new WindowViewMock(), session);
session.setUseSoftTabs(false);
@@ -372,12 +376,12 @@ module.exports = {
},
"test: undo/redo for delete line" : function() {
- var session = new EditSession(["111", "222", "333"]);
+ var session = new Buffer(["111", "222", "333"]);
var undoManager = new UndoManager();
session.setUndoManager(undoManager);
var initialText = session.toString();
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.removeLines();
var step1 = session.toString();
@@ -412,38 +416,38 @@ module.exports = {
},
"test: remove left should remove character left of the cursor" : function() {
- var session = new EditSession(["123", "456"]);
+ var session = new Buffer(["123", "456"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 1);
- editor.remove("left");
+ editor.removeLeft();
assert.equal(session.toString(), "123\n56");
},
"test: remove left should remove line break if cursor is at line start" : function() {
- var session = new EditSession(["123", "456"]);
+ var session = new Buffer(["123", "456"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 0);
- editor.remove("left");
+ editor.removeLeft();
assert.equal(session.toString(), "123456");
},
"test: remove left should remove tabsize spaces if cursor is on a tab stop and preceeded by spaces" : function() {
- var session = new EditSession(["123", " 456"]);
+ var session = new Buffer(["123", " 456"]);
session.setUseSoftTabs(true);
session.setTabSize(4);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 8);
- editor.remove("left");
+ editor.removeLeft();
assert.equal(session.toString(), "123\n 456");
},
"test: transpose at line start should be a noop": function() {
- var session = new EditSession(["123", "4567", "89"]);
+ var session = new Buffer(["123", "4567", "89"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 0);
editor.transposeLetters();
@@ -451,9 +455,9 @@ module.exports = {
},
"test: transpose in line should swap the charaters before and after the cursor": function() {
- var session = new EditSession(["123", "4567", "89"]);
+ var session = new Buffer(["123", "4567", "89"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 2);
editor.transposeLetters();
@@ -461,9 +465,9 @@ module.exports = {
},
"test: transpose at line end should swap the last two characters": function() {
- var session = new EditSession(["123", "4567", "89"]);
+ var session = new Buffer(["123", "4567", "89"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 4);
editor.transposeLetters();
@@ -471,9 +475,9 @@ module.exports = {
},
"test: transpose with non empty selection should be a noop": function() {
- var session = new EditSession(["123", "4567", "89"]);
+ var session = new Buffer(["123", "4567", "89"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 1);
editor.getSelection().selectRight();
editor.transposeLetters();
@@ -482,71 +486,31 @@ module.exports = {
},
"test: transpose should move the cursor behind the last swapped character": function() {
- var session = new EditSession(["123", "4567", "89"]);
+ var session = new Buffer(["123", "4567", "89"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 2);
editor.transposeLetters();
assert.position(editor.getCursorPosition(), 1, 3);
},
"test: remove to line end": function() {
- var session = new EditSession(["123", "4567", "89"]);
+ var session = new Buffer(["123", "4567", "89"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 2);
editor.removeToLineEnd();
assert.equal(session.getValue(), ["123", "45", "89"].join("\n"));
},
"test: remove to line end at line end should remove the new line": function() {
- var session = new EditSession(["123", "4567", "89"]);
+ var session = new Buffer(["123", "4567", "89"]);
- var editor = new Editor(new MockRenderer(), session);
+ var editor = new Editor(new WindowViewMock(), session);
editor.moveCursorTo(1, 4);
editor.removeToLineEnd();
assert.position(editor.getCursorPosition(), 1, 4);
assert.equal(session.getValue(), ["123", "456789"].join("\n"));
- },
-
- "test: transform selection to uppercase": function() {
- var session = new EditSession(["ajax", "dot", "org"]);
-
- var editor = new Editor(new MockRenderer(), session);
- editor.moveCursorTo(1, 0);
- editor.getSelection().selectLineEnd();
- editor.toUpperCase()
- assert.equal(session.getValue(), ["ajax", "DOT", "org"].join("\n"));
- },
-
- "test: transform word to uppercase": function() {
- var session = new EditSession(["ajax", "dot", "org"]);
-
- var editor = new Editor(new MockRenderer(), session);
- editor.moveCursorTo(1, 0);
- editor.toUpperCase()
- assert.equal(session.getValue(), ["ajax", "DOT", "org"].join("\n"));
- assert.position(editor.getCursorPosition(), 1, 0);
- },
-
- "test: transform selection to lowercase": function() {
- var session = new EditSession(["AJAX", "DOT", "ORG"]);
-
- var editor = new Editor(new MockRenderer(), session);
- editor.moveCursorTo(1, 0);
- editor.getSelection().selectLineEnd();
- editor.toLowerCase()
- assert.equal(session.getValue(), ["AJAX", "dot", "ORG"].join("\n"));
- },
-
- "test: transform word to lowercase": function() {
- var session = new EditSession(["AJAX", "DOT", "ORG"]);
-
- var editor = new Editor(new MockRenderer(), session);
- editor.moveCursorTo(1, 0);
- editor.toLowerCase()
- assert.equal(session.getValue(), ["AJAX", "dot", "ORG"].join("\n"));
- assert.position(editor.getCursorPosition(), 1, 0);
}
};
@@ -554,4 +518,4 @@ module.exports = {
if (typeof module !== "undefined" && module === require.main) {
require("asyncjs").test.testcase(module.exports).exec()
-}
+}
\ No newline at end of file
diff --git a/ace/keyboard/hash_handler.js b/ace/keyboard/hash_handler.js
new file mode 100644
index 00000000..d06374d3
--- /dev/null
+++ b/ace/keyboard/hash_handler.js
@@ -0,0 +1,116 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Julian Viereck (julian.viereck@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var keyUtil = require("ace/lib/keys");
+
+function HashHandler(config) {
+ this.setConfig(config);
+}
+
+(function() {
+ function splitSafe(s, separator, limit, bLowerCase) {
+ return (bLowerCase && s.toLowerCase() || s)
+ .replace(/(?:^\s+|\n|\s+$)/g, "")
+ .split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999);
+ }
+
+ function parseKeys(keys, val, ret) {
+ var key,
+ hashId = 0,
+ parts = splitSafe(keys, "\\-", null, true),
+ i = 0,
+ l = parts.length;
+
+ for (; i < l; ++i) {
+ if (keyUtil.KEY_MODS[parts[i]])
+ hashId = hashId | keyUtil.KEY_MODS[parts[i]];
+ else
+ key = parts[i] || "-"; //when empty, the splitSafe removed a '-'
+ }
+
+ (ret[hashId] || (ret[hashId] = {}))[key] = val;
+ return ret;
+ }
+
+ function objectReverse(obj, keySplit) {
+ var i, j, l, key,
+ ret = {};
+ for (i in obj) {
+ key = obj[i];
+ if (keySplit && typeof key == "string") {
+ key = key.split(keySplit);
+ for (j = 0, l = key.length; j < l; ++j)
+ parseKeys.call(this, key[j], i, ret);
+ }
+ else {
+ parseKeys.call(this, key, i, ret);
+ }
+ }
+ return ret;
+ }
+
+ this.setConfig = function(config) {
+ this.$config = config;
+ if (typeof this.$config.reverse == "undefined")
+ this.$config.reverse = objectReverse.call(this, this.$config, "|");
+ };
+
+ /**
+ * This function is called by keyBinding.
+ */
+ this.handleKeyboard = function(data, hashId, textOrKey, keyCode) {
+ // Figure out if a commandKey was pressed or just some text was insert.
+ if (hashId != 0 || keyCode != 0) {
+ return {
+ command: (this.$config.reverse[hashId] || {})[textOrKey]
+ }
+ } else {
+ return {
+ command: "inserttext",
+ args: {
+ text: textOrKey
+ }
+ }
+ }
+ }
+}).call(HashHandler.prototype)
+
+exports.HashHandler = HashHandler;
+});
diff --git a/ace/keyboard/keybinding.js b/ace/keyboard/keybinding.js
new file mode 100644
index 00000000..f8b640bc
--- /dev/null
+++ b/ace/keyboard/keybinding.js
@@ -0,0 +1,119 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Julian Viereck
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var useragent = require("ace/lib/useragent");
+var keyUtil = require("ace/lib/keys");
+var event = require("ace/lib/event");
+require("ace/commands/default_commands");
+
+var KeyBinding = function(editor) {
+ this.$editor = editor;
+ this.$data = { };
+ this.$keyboardHandler = null;
+};
+
+(function() {
+ this.setKeyboardHandler = function(keyboardHandler) {
+ if (this.$keyboardHandler != keyboardHandler) {
+ this.$data = { };
+ this.$keyboardHandler = keyboardHandler;
+ }
+ };
+
+ this.getKeyboardHandler = function() {
+ return this.$keyboardHandler;
+ };
+
+ this.$callKeyboardHandler = function (e, hashId, keyOrText, keyCode) {
+ var env = {editor: this.$editor};
+ var toExecute;
+ var commands = this.$editor.commands;
+
+ if (this.$keyboardHandler) {
+ toExecute =
+ this.$keyboardHandler.handleKeyboard(this.$data, hashId, keyOrText, keyCode, e);
+ }
+
+
+ // If there is nothing to execute yet, then use the default keymapping.
+ if (!toExecute || !toExecute.command) {
+ if (hashId != 0 || keyCode != 0) {
+ toExecute = {
+ command: commands.findKeyCommand(env, hashId, keyOrText)
+ }
+ } else {
+ toExecute = {
+ command: "inserttext",
+ args: {
+ text: keyOrText
+ }
+ }
+ }
+ }
+
+ var success = false;
+ if (toExecute && toExecute.command) {
+ success = commands.exec(
+ toExecute.command,
+ env, toExecute.args
+ );
+ if (success) {
+ event.stopEvent(e);
+ }
+ }
+ return success;
+ };
+
+ this.onCommandKey = function(e, hashId, keyCode, keyString) {
+ // In case there is no keyString, try to interprete the keyCode.
+ if (!keyString) {
+ keyString = keyUtil.keyCodeToString(keyCode);
+ }
+ return this.$callKeyboardHandler(e, hashId, keyString, keyCode);
+ };
+
+ this.onTextInput = function(text) {
+ return this.$callKeyboardHandler({}, 0, text, 0);
+ }
+
+}).call(KeyBinding.prototype);
+
+exports.KeyBinding = KeyBinding;
+});
diff --git a/ace/keyboard/keybinding/emacs.js b/ace/keyboard/keybinding/emacs.js
new file mode 100644
index 00000000..ce0cbc06
--- /dev/null
+++ b/ace/keyboard/keybinding/emacs.js
@@ -0,0 +1,149 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Julian Viereck (julian.viereck@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var StateHandler = require("ace/keyboard/state_handler").StateHandler;
+var matchCharacterOnly = require("ace/keyboard/state_handler").matchCharacterOnly;
+
+var emacsState = {
+ start: [
+ {
+ key: "ctrl-x",
+ then: "c-x"
+ },
+ {
+ regex: [ "(?:command-([0-9]*))*", "(down|ctrl-n)" ],
+ exec: "golinedown",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: 1
+ }
+ ]
+ },
+ {
+ regex: [ "(?:command-([0-9]*))*", "(right|ctrl-f)" ],
+ exec: "gotoright",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: 1
+ }
+ ]
+ },
+ {
+ regex: [ "(?:command-([0-9]*))*", "(up|ctrl-p)" ],
+ exec: "golineup",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: 1
+ }
+ ]
+ },
+ {
+ regex: [ "(?:command-([0-9]*))*", "(left|ctrl-b)" ],
+ exec: "gotoleft",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: 1
+ }
+ ]
+ },
+ {
+ comment: "This binding matches all printable characters except numbers as long as they are no numbers and print them n times.",
+ regex: [ "(?:command-([0-9]*))", "([^0-9]+)*" ],
+ match: matchCharacterOnly,
+ exec: "inserttext",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: "1"
+ },
+ {
+ name: "text",
+ match: 2
+ }
+ ]
+ },
+ {
+ comment: "This binding matches numbers as long as there is no meta_number in the buffer.",
+ regex: [ "(command-[0-9]*)*", "([0-9]+)" ],
+ match: matchCharacterOnly,
+ disallowMatches: [ 1 ],
+ exec: "inserttext",
+ params: [
+ {
+ name: "text",
+ match: 2,
+ type: "text"
+ }
+ ]
+ },
+ {
+ regex: [ "command-([0-9]*)", "(command-[0-9]|[0-9])" ],
+ comment: "Stops execution if the regex /meta_[0-9]+/ matches to avoid resetting the buffer."
+ }
+ ],
+ "c-x": [
+ {
+ key: "ctrl-g",
+ then: "start"
+ },
+ {
+ key: "ctrl-s",
+ exec: "save",
+ then: "start"
+ }
+ ]
+};
+
+exports.Emacs = new StateHandler(emacsState);
+
+});
diff --git a/ace/keyboard/keybinding/vim.js b/ace/keyboard/keybinding/vim.js
new file mode 100644
index 00000000..999bfa75
--- /dev/null
+++ b/ace/keyboard/keybinding/vim.js
@@ -0,0 +1,179 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Julian Viereck (julian.viereck@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var StateHandler = require("ace/keyboard/state_handler").StateHandler;
+var matchCharacterOnly = require("ace/keyboard/state_handler").matchCharacterOnly;
+
+var vimStates = {
+ start: [
+ {
+ key: "i",
+ then: "insertMode"
+ },
+ {
+ key: "d",
+ then: "deleteMode"
+ },
+ {
+ key: "a",
+ exec: "gotoright",
+ then: "insertMode"
+ },
+ {
+ key: "shift-i",
+ exec: "gotolinestart",
+ then: "insertMode"
+ },
+ {
+ key: "shift-a",
+ exec: "gotolineend",
+ then: "insertMode"
+ },
+ {
+ key: "shift-c",
+ exec: "removetolineend",
+ then: "insertMode"
+ },
+ {
+ key: "shift-r",
+ exec: "overwrite",
+ then: "replaceMode"
+ },
+ {
+ regex: [ "([0-9]*)", "(k|up)" ],
+ exec: "golineup",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: 1
+ }
+ ]
+ },
+ {
+ regex: [ "([0-9]*)", "(j|down|enter)" ],
+ exec: "golinedown",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: 1
+ }
+ ]
+ },
+ {
+ regex: [ "([0-9]*)", "(l|right)" ],
+ exec: "gotoright",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: 1
+ }
+ ]
+ },
+ {
+ regex: [ "([0-9]*)", "(h|left)" ],
+ exec: "gotoleft",
+ params: [
+ {
+ name: "times",
+ match: 1,
+ type: "number",
+ defaultValue: 1
+ }
+ ]
+ },
+ {
+ key: "shift-g",
+ exec: "gotoend"
+ },
+ {
+ key: "b",
+ exec: "gotowordleft"
+ },
+ {
+ key: "e",
+ exec: "gotowordright"
+ },
+ {
+ key: "x",
+ exec: "del"
+ },
+ {
+ key: "shift-x",
+ exec: "backspace"
+ },
+ {
+ key: "shift-d",
+ exec: "removetolineend"
+ },
+ {
+ comment: "Catch some keyboard input to stop it here",
+ match: matchCharacterOnly
+ }
+ ],
+ insertMode: [
+ {
+ key: "esc",
+ then: "start"
+ }
+ ],
+ replaceMode: [
+ {
+ key: "esc",
+ exec: "overwrite",
+ then: "start"
+ }
+ ],
+ deleteMode: [
+ {
+ key: "d",
+ exec: "removeline",
+ then: "start"
+ }
+ ]
+};
+
+exports.Vim = new StateHandler(vimStates);
+
+});
diff --git a/lib/ace/keyboard/state_handler.js b/ace/keyboard/state_handler.js
similarity index 71%
rename from lib/ace/keyboard/state_handler.js
rename to ace/keyboard/state_handler.js
index 8265bbe1..fd443acd 100644
--- a/lib/ace/keyboard/state_handler.js
+++ b/ace/keyboard/state_handler.js
@@ -1,35 +1,41 @@
/* ***** BEGIN LICENSE BLOCK *****
- * Distributed under the BSD license:
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
- * 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.
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Julian Viereck (julian.viereck@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** 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.
@@ -40,13 +46,13 @@ function StateHandler(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) {
+ for (state in keymapping) {
this.$buildBindingsRegex(keymapping[state]);
}
return keymapping;
@@ -58,8 +64,7 @@ StateHandler.prototype = {
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.key = new RegExp('^' + binding.regex[1] + '$');
binding.regex = new RegExp(binding.regex.join('') + '$');
} else if (binding.regex) {
binding.regex = new RegExp(binding.regex + '$');
@@ -67,7 +72,7 @@ StateHandler.prototype = {
});
},
- $composeBuffer: function(data, hashId, key, e) {
+ $composeBuffer: function(data, hashId, key) {
// Initialize the data object.
if (data.state == null || data.buffer == null) {
data.state = "start";
@@ -96,23 +101,17 @@ StateHandler.prototype = {
data.buffer = bufferToUse;
}
- var bufferObj = {
- bufferToUse: bufferToUse,
- symbolicName: symbolicName
+ return {
+ bufferToUse: bufferToUse,
+ symbolicName: symbolicName
};
-
- if (e) {
- bufferObj.keyIdentifier = e.keyIdentifier;
- }
-
- return bufferObj;
},
- $find: function(data, buffer, symbolicName, hashId, key, keyIdentifier) {
+ $find: function(data, buffer, symbolicName, hashId, key) {
// 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.
+ // Loop over all the bindings of the keymapp until a match is found.
this.keymapping[data.state].some(function(binding) {
var match;
@@ -127,7 +126,7 @@ StateHandler.prototype = {
}
// Check if the match function matches.
- if (binding.match && !binding.match(buffer, hashId, key, symbolicName, keyIdentifier)) {
+ if (binding.match && !binding.match(buffer, hashId, key, symbolicName)) {
return false;
}
@@ -191,26 +190,23 @@ StateHandler.prototype = {
}
},
- /*
+ /**
* This function is called by keyBinding.
*/
- handleKeyboard: function(data, hashId, key, keyCode, e) {
- if (hashId == -1)
- hashId = 0
+ handleKeyboard: function(data, hashId, key) {
// 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.
+ // which results in "shift-shift-g" which doesn't make senese.
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 r = this.$composeBuffer(data, hashId, key);
var buffer = r.bufferToUse;
var symbolicName = r.symbolicName;
- var keyId = r.keyIdentifier;
- r = this.$find(data, buffer, symbolicName, hashId, key, keyId);
+ r = this.$find(data, buffer, symbolicName, hashId, key);
if (DEBUG) {
console.log("KeyboardStateMapper#match", buffer, symbolicName, r);
}
@@ -219,11 +215,12 @@ StateHandler.prototype = {
}
}
-/*
+/**
* 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
+ * @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
diff --git a/ace/keyboard/textinput.js b/ace/keyboard/textinput.js
new file mode 100644
index 00000000..302639fa
--- /dev/null
+++ b/ace/keyboard/textinput.js
@@ -0,0 +1,272 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Mihai Sucan
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var event = require("ace/lib/event");
+var useragent = require("ace/lib/useragent");
+var dom = require("ace/lib/dom");
+
+var TextInput = function(parentNode, host) {
+
+ var text = dom.createElement("textarea");
+ text.style.left = "-10000px";
+ parentNode.appendChild(text);
+
+ var PLACEHOLDER = String.fromCharCode(0);
+ sendText();
+
+ var inCompostion = false;
+ var copied = false;
+ var pasted = false;
+ var tempStyle = '';
+
+ function select() {
+ try {
+ text.select();
+ } catch (e) {}
+ };
+
+ function sendText(valueToSend) {
+ if (!copied) {
+ var value = valueToSend || text.value;
+ if (value) {
+ if (value.charCodeAt(value.length-1) == PLACEHOLDER.charCodeAt(0))
+ value = value.slice(0, -1);
+
+ if (value) {
+ if (pasted)
+ host.onPaste(value);
+ else
+ host.onTextInput(value);
+ }
+
+ // If editor is no longer focused we quit immediately, since
+ // it means that something else is in charge now.
+ if (!isFocused())
+ return false;
+ }
+ }
+
+ copied = false;
+ pasted = false;
+
+ // Safari doesn't fire copy events if no text is selected
+ text.value = PLACEHOLDER;
+ select();
+ }
+
+ var onTextInput = function(e) {
+ setTimeout(function () {
+ if (!inCompostion)
+ sendText(e.data);
+ }, 0);
+ };
+
+ var onPropertyChange = function(e) {
+ if (useragent.isIE && text.value.charCodeAt(0) > 128) return;
+ setTimeout(function() {
+ if (!inCompostion)
+ sendText();
+ }, 0);
+ };
+
+ var onCompositionStart = function(e) {
+ inCompostion = true;
+ host.onCompositionStart();
+ if (!useragent.isGecko) setTimeout(onCompositionUpdate, 0);
+ };
+
+ var onCompositionUpdate = function() {
+ if (!inCompostion) return;
+ host.onCompositionUpdate(text.value);
+ };
+
+ var onCompositionEnd = function(e) {
+ inCompostion = false;
+ host.onCompositionEnd();
+ };
+
+ var onCopy = function(e) {
+ copied = true;
+ var copyText = host.getCopyText();
+ if(copyText)
+ text.value = copyText;
+ else
+ e.preventDefault();
+ select();
+ setTimeout(function () {
+ sendText();
+ }, 0);
+ };
+
+ var onCut = function(e) {
+ copied = true;
+ var copyText = host.getCopyText();
+ if(copyText) {
+ text.value = copyText;
+ host.onCut();
+ } else
+ e.preventDefault();
+ select();
+ setTimeout(function () {
+ sendText();
+ }, 0);
+ };
+
+ event.addCommandKeyListener(text, host.onCommandKey.bind(host));
+ if (useragent.isIE) {
+ var keytable = { 13:1, 27:1 };
+ event.addListener(text, "keyup", function (e) {
+ if (inCompostion && (!text.value || keytable[e.keyCode]))
+ setTimeout(onCompositionEnd, 0);
+ if ((text.value.charCodeAt(0)|0) < 129) {
+ return;
+ };
+ inCompostion ? onCompositionUpdate() : onCompositionStart();
+ });
+ };
+
+ if ("onpropertychange" in text && !("oninput" in text))
+ event.addListener(text, "propertychange", onPropertyChange);
+ else
+ event.addListener(text, "input", onTextInput);
+
+ event.addListener(text, "paste", function(e) {
+ // Mark that the next input text comes from past.
+ pasted = true;
+ // Some browsers support the event.clipboardData API. Use this to get
+ // the pasted content which increases speed if pasting a lot of lines.
+ if (e.clipboardData && e.clipboardData.getData) {
+ sendText(e.clipboardData.getData("text/plain"));
+ e.preventDefault();
+ }
+ else {
+ // If a browser doesn't support any of the things above, use the regular
+ // method to detect the pasted input.
+ onPropertyChange();
+ }
+ });
+
+ if (useragent.isIE) {
+ event.addListener(text, "beforecopy", function(e) {
+ var copyText = host.getCopyText();
+ if(copyText)
+ clipboardData.setData("Text", copyText);
+ else
+ e.preventDefault();
+ });
+ event.addListener(parentNode, "keydown", function(e) {
+ if (e.ctrlKey && e.keyCode == 88) {
+ var copyText = host.getCopyText();
+ if (copyText) {
+ clipboardData.setData("Text", copyText);
+ host.onCut();
+ }
+ event.preventDefault(e)
+ }
+ });
+ }
+ else {
+ event.addListener(text, "copy", onCopy);
+ event.addListener(text, "cut", onCut);
+ }
+
+ event.addListener(text, "compositionstart", onCompositionStart);
+ if (useragent.isGecko) {
+ event.addListener(text, "text", onCompositionUpdate);
+ };
+ if (useragent.isWebKit) {
+ event.addListener(text, "keyup", onCompositionUpdate);
+ };
+ event.addListener(text, "compositionend", onCompositionEnd);
+
+ event.addListener(text, "blur", function() {
+ host.onBlur();
+ });
+
+ event.addListener(text, "focus", function() {
+ host.onFocus();
+ select();
+ });
+
+ this.focus = function() {
+ host.onFocus();
+ select();
+ text.focus();
+ };
+
+ this.blur = function() {
+ text.blur();
+ };
+
+ function isFocused() {
+ return document.activeElement === text;
+ };
+ this.isFocused = isFocused;
+
+ this.getElement = function() {
+ return text;
+ };
+
+ this.onContextMenu = function(mousePos, isEmpty){
+ if (mousePos) {
+ if(!tempStyle)
+ tempStyle = text.style.cssText;
+ text.style.cssText = 'position:fixed; z-index:1000;' +
+ 'left:' + (mousePos.x - 2) + 'px; top:' + (mousePos.y - 2) + 'px;'
+
+ }
+ if (isEmpty)
+ text.value='';
+ }
+
+ this.onContextMenuClose = function(){
+ setTimeout(function () {
+ if (tempStyle) {
+ text.style.cssText = tempStyle;
+ tempStyle = '';
+ }
+ sendText();
+ }, 0);
+ }
+};
+
+exports.TextInput = TextInput;
+});
diff --git a/ace/lib/browser_focus.js b/ace/lib/browser_focus.js
new file mode 100644
index 00000000..945573d9
--- /dev/null
+++ b/ace/lib/browser_focus.js
@@ -0,0 +1,103 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Irakli Gozalishvili (http://jeditoolkit.com)
+ * Julian Viereck
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var event = require("ace/lib/event");
+var EventEmitter = require("ace/lib/event_emitter").EventEmitter;
+
+/**
+ * This class keeps track of the focus state of the given window.
+ * Focus changes for example when the user switches a browser tab,
+ * goes to the location bar or switches to another application.
+ */
+var BrowserFocus = function(win) {
+ win = win || window;
+
+ this.lastFocus = new Date().getTime();
+ this._isFocused = true;
+
+ var _self = this;
+ // IE < 9 supports focusin and focusout events
+ if ("onfocusin" in win.document) {
+ event.addListener(win.document, "focusin", function(e) {
+ _self._setFocused(true);
+ });
+
+ event.addListener(win.document, "focusout", function(e) {
+ _self._setFocused(!!e.toElement);
+ });
+ }
+ else {
+ event.addListener(win, "blur", function(e) {
+ _self._setFocused(false);
+ });
+
+ event.addListener(win, "focus", function(e) {
+ _self._setFocused(true);
+ });
+ }
+};
+
+(function(){
+
+ oop.implement(this, EventEmitter);
+
+ this.isFocused = function() {
+ return this._isFocused;
+ };
+
+ this._setFocused = function(isFocused) {
+ if (this._isFocused == isFocused)
+ return;
+
+ if (isFocused)
+ this.lastFocus = new Date().getTime();
+
+ this._isFocused = isFocused;
+ this._emit("changeFocus");
+ };
+
+}).call(BrowserFocus.prototype);
+
+
+exports.BrowserFocus = BrowserFocus;
+});
diff --git a/ace/lib/dom.js b/ace/lib/dom.js
new file mode 100644
index 00000000..9bc7bf2f
--- /dev/null
+++ b/ace/lib/dom.js
@@ -0,0 +1,263 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Mihai Sucan
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var XHTML_NS = "http://www.w3.org/1999/xhtml";
+
+exports.createElement = function(tag, ns) {
+ return document.createElementNS ?
+ document.createElementNS(ns || XHTML_NS, tag) :
+ document.createElement(tag);
+};
+
+exports.setText = function(elem, text) {
+ if (elem.innerText !== undefined) {
+ elem.innerText = text;
+ }
+ if (elem.textContent !== undefined) {
+ elem.textContent = text;
+ }
+};
+
+if (!document.documentElement.classList) {
+ 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;
+ };
+} else {
+ exports.hasCssClass = function(el, name) {
+ return el.classList.contains(name);
+ };
+
+ exports.addCssClass = function(el, name) {
+ el.classList.add(name);
+ };
+
+ exports.removeCssClass = function(el, name) {
+ el.classList.remove(name);
+ };
+
+ exports.toggleCssClass = function(el, name) {
+ return el.classList.toggle(name);
+ };
+}
+
+/**
+ * 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.importCssString = function(cssText, doc){
+ doc = doc || document;
+
+ if (doc.createStyleSheet) {
+ var sheet = doc.createStyleSheet();
+ sheet.cssText = cssText;
+ }
+ else {
+ var style = doc.createElementNS ?
+ doc.createElementNS(XHTML_NS, "style") :
+ doc.createElement("style");
+
+ style.appendChild(doc.createTextNode(cssText));
+
+ var head = doc.getElementsByTagName("head")[0] || doc.documentElement;
+ head.appendChild(style);
+ }
+};
+
+exports.getInnerWidth = function(element) {
+ return (parseInt(exports.computedStyle(element, "paddingLeft"))
+ + parseInt(exports.computedStyle(element, "paddingRight")) + element.clientWidth);
+};
+
+exports.getInnerHeight = function(element) {
+ return (parseInt(exports.computedStyle(element, "paddingTop"))
+ + parseInt(exports.computedStyle(element, "paddingBottom")) + element.clientHeight);
+};
+
+if (window.pageYOffset !== undefined) {
+ exports.getPageScrollTop = function() {
+ return window.pageYOffset;
+ };
+
+ exports.getPageScrollLeft = function() {
+ return window.pageXOffset;
+ };
+}
+else {
+ exports.getPageScrollTop = function() {
+ return document.body.scrollTop;
+ };
+
+ exports.getPageScrollLeft = function() {
+ return document.body.scrollLeft;
+ };
+}
+
+if (window.getComputedStyle)
+ exports.computedStyle = function(element, style) {
+ if (style)
+ return (window.getComputedStyle(element, "") || {})[style] || "";
+ return window.getComputedStyle(element, "") || {}
+ };
+else
+ exports.computedStyle = function(element, style) {
+ if (style)
+ return element.currentStyle[style];
+ return element.currentStyle
+ };
+
+exports.scrollbarWidth = function() {
+ var inner = exports.createElement("p");
+ inner.style.width = "100%";
+ inner.style.minWidth = "0px";
+ inner.style.height = "200px";
+
+ var outer = exports.createElement("div");
+ var style = outer.style;
+
+ style.position = "absolute";
+ style.left = "-10000px";
+ style.overflow = "hidden";
+ style.width = "200px";
+ style.minWidth = "0px";
+ style.height = "150px";
+
+ outer.appendChild(inner);
+
+ var body = document.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;
+};
+
+/**
+ * Optimized set innerHTML. This is faster than plain innerHTML if the element
+ * already contains a lot of child elements.
+ *
+ * See http://blog.stevenlevithan.com/archives/faster-than-innerhtml for details
+ */
+exports.setInnerHtml = function(el, innerHtml) {
+ var element = el.cloneNode(false);//document.createElement("div");
+ element.innerHTML = innerHtml;
+ el.parentNode.replaceChild(element, el);
+ return element;
+};
+
+exports.setInnerText = function(el, innerText) {
+ if (document.body && "textContent" in document.body)
+ el.textContent = innerText;
+ else
+ el.innerText = innerText;
+
+};
+
+exports.getInnerText = function(el) {
+ if (document.body && "textContent" in document.body)
+ return el.textContent;
+ else
+ return el.innerText || el.textContent || "";
+};
+
+exports.getParentWindow = function(document) {
+ return document.defaultView || document.parentWindow;
+};
+
+});
diff --git a/ace/lib/event.js b/ace/lib/event.js
new file mode 100644
index 00000000..fc5f17d8
--- /dev/null
+++ b/ace/lib/event.js
@@ -0,0 +1,325 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var keys = require("ace/lib/keys");
+var useragent = require("ace/lib/useragent");
+var dom = require("ace/lib/dom");
+
+exports.addListener = function(elem, type, callback) {
+ if (elem.addEventListener) {
+ return elem.addEventListener(type, callback, false);
+ }
+ if (elem.attachEvent) {
+ var wrapper = function() {
+ callback(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;
+};
+
+exports.getDocumentX = function(e) {
+ if (e.clientX) {
+ return e.clientX + dom.getPageScrollLeft();
+ } else {
+ return e.pageX;
+ }
+};
+
+exports.getDocumentY = function(e) {
+ if (e.clientY) {
+ return e.clientY + dom.getPageScrollTop();
+ } else {
+ return e.pageY;
+ }
+};
+
+/**
+ * @return {Number} 0 for left button, 1 for middle button, 2 for right button
+ */
+exports.getButton = function(e) {
+ if (e.type == "dblclick")
+ return 0;
+ else if (e.type == "contextmenu")
+ return 2;
+
+ // DOM Event
+ if (e.preventDefault) {
+ return e.button;
+ }
+ // old IE
+ else {
+ return {1:0, 2:2, 4:1}[e.button];
+ }
+};
+
+if (document.documentElement.setCapture) {
+ exports.capture = function(el, eventHandler, releaseCaptureHandler) {
+ function onMouseMove(e) {
+ eventHandler(e);
+ return exports.stopPropagation(e);
+ }
+
+ var called = false;
+ function onReleaseCapture(e) {
+ eventHandler(e);
+
+ if (!called) {
+ called = true;
+ releaseCaptureHandler();
+ }
+
+ exports.removeListener(el, "mousemove", eventHandler);
+ exports.removeListener(el, "mouseup", onReleaseCapture);
+ exports.removeListener(el, "losecapture", onReleaseCapture);
+
+ el.releaseCapture();
+ }
+
+ exports.addListener(el, "mousemove", eventHandler);
+ exports.addListener(el, "mouseup", onReleaseCapture);
+ exports.addListener(el, "losecapture", onReleaseCapture);
+ el.setCapture();
+ };
+}
+else {
+ exports.capture = function(el, eventHandler, releaseCaptureHandler) {
+ function onMouseMove(e) {
+ eventHandler(e);
+ e.stopPropagation();
+ }
+
+ function onMouseUp(e) {
+ eventHandler && eventHandler(e);
+ releaseCaptureHandler && releaseCaptureHandler();
+
+ document.removeEventListener("mousemove", onMouseMove, true);
+ document.removeEventListener("mouseup", onMouseUp, true);
+
+ e.stopPropagation();
+ }
+
+ document.addEventListener("mousemove", onMouseMove, true);
+ document.addEventListener("mouseup", onMouseUp, true);
+ };
+}
+
+exports.addMouseWheelListener = function(el, callback) {
+ var max = 0;
+ var listener = function(e) {
+ if (e.wheelDelta !== undefined) {
+
+ // some versions of Safari (e.g. 5.0.5) report insanely high
+ // scroll values. These browsers require a higher factor
+ if (Math.abs(e.wheelDeltaY) > max)
+ max = Math.abs(e.wheelDeltaY)
+
+ if (max > 5000)
+ factor = 400;
+ else
+ 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;
+ }
+ }
+ else {
+ 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.addListener(el, "DOMMouseScroll", listener);
+ exports.addListener(el, "mousewheel", listener);
+};
+
+exports.addMultiMouseDownListener = function(el, button, count, timeout, callback) {
+ var clicks = 0;
+ var startX, startY;
+
+ var listener = function(e) {
+ clicks += 1;
+ if (clicks == 1) {
+ startX = e.clientX;
+ startY = e.clientY;
+
+ setTimeout(function() {
+ clicks = 0;
+ }, timeout || 600);
+ }
+
+ var isButton = exports.getButton(e) == button;
+ if (!isButton || Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5)
+ clicks = 0;
+
+ if (clicks == count) {
+ clicks = 0;
+ callback(e);
+ }
+
+ if (isButton)
+ return exports.preventDefault(e);
+ };
+
+ exports.addListener(el, "mousedown", listener);
+ useragent.isIE && exports.addListener(el, "dblclick", listener);
+};
+
+function normalizeCommandKeys(callback, e, keyCode) {
+ var hashId = 0;
+ if (useragent.isOpera && useragent.isMac) {
+ hashId = 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0)
+ | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
+ } else {
+ hashId = 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0)
+ | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
+ }
+
+ if (keyCode in keys.MODIFIER_KEYS) {
+ switch (keys.MODIFIER_KEYS[keyCode]) {
+ case "Alt":
+ hashId = 2;
+ break;
+ case "Shift":
+ hashId = 4;
+ break
+ case "Ctrl":
+ hashId = 1;
+ break;
+ default:
+ hashId = 8;
+ break;
+ }
+ keyCode = 0;
+ }
+
+ if (hashId & 8 && (keyCode == 91 || keyCode == 93)) {
+ keyCode = 0;
+ }
+
+ // 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 == 0 && !(keyCode in keys.FUNCTION_KEYS)) {
+ return false;
+ }
+
+ return callback(e, hashId, keyCode);
+}
+
+exports.addCommandKeyListener = function(el, callback) {
+ var addListener = exports.addListener;
+ if (useragent.isOldGecko) {
+ // 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 lastDown = null;
+
+ addListener(el, "keydown", function(e) {
+ lastDown = e.keyIdentifier || e.keyCode;
+ return normalizeCommandKeys(callback, e, e.keyCode);
+ });
+
+ // repeated keys are fired as keypress and not keydown events
+ if (useragent.isMac && useragent.isOpera) {
+ addListener(el, "keypress", function(e) {
+ var keyId = e.keyIdentifier || e.keyCode;
+ if (lastDown !== keyId) {
+ return normalizeCommandKeys(callback, e, e.keyCode);
+ } else {
+ lastDown = null;
+ }
+ });
+ }
+ }
+};
+
+});
diff --git a/ace/lib/event_emitter.js b/ace/lib/event_emitter.js
new file mode 100644
index 00000000..de6523e1
--- /dev/null
+++ b/ace/lib/event_emitter.js
@@ -0,0 +1,92 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Irakli Gozalishvili (http://jeditoolkit.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var EventEmitter = {};
+
+EventEmitter._emit =
+EventEmitter._dispatchEvent = function(eventName, e) {
+ this._eventRegistry = this._eventRegistry || {};
+
+ var listeners = this._eventRegistry[eventName];
+ if (!listeners || !listeners.length) return;
+
+ var e = e || {};
+ e.type = eventName;
+
+ for (var i=0; i= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (++i >= len)
+ throw new TypeError();
+ } while (true);
+ }
+
+ for (; i < len; i++) {
+ if (i in this)
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+
+ return rv;
+ };
+}
+
+// ES5 15.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 len = +this.length;
+ if (typeof fun !== "function")
+ throw new TypeError();
+
+ // no value to return if no initial value, empty array
+ if (len === 0 && arguments.length === 1)
+ throw new TypeError();
+
+ var i = len - 1;
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i--];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (--i < 0)
+ throw new TypeError();
+ } while (true);
+ }
+
+ for (; i >= 0; i--) {
+ if (i in this)
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+
+ return rv;
+ };
+}
+
+// ES5 15.4.4.14
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function indexOf(value /*, fromIndex */ ) {
+ var length = this.length;
+ if (!length)
+ return -1;
+ var i = arguments[1] || 0;
+ if (i >= length)
+ return -1;
+ if (i < 0)
+ i += length;
+ for (; i < length; i++) {
+ if (!owns(this, i))
+ continue;
+ if (value === this[i])
+ return i;
+ }
+ return -1;
+ };
+}
+
+// ES5 15.4.4.15
+if (!Array.prototype.lastIndexOf) {
+ Array.prototype.lastIndexOf = function lastIndexOf(value /*, fromIndex */) {
+ var length = this.length;
+ if (!length)
+ return -1;
+ var i = arguments[1] || length;
+ if (i < 0)
+ i += length;
+ i = Math.min(i, length - 1);
+ for (; i >= 0; i--) {
+ if (!owns(this, i))
+ continue;
+ if (value === this[i])
+ return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+// ======
+//
+
+// ES5 15.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.prototype;
+ // or undefined if not available in this engine
+ };
+}
+
+// ES5 15.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 undefined;
+
+ var despriptor, getter, setter;
+
+ // If object has a property then it's for sure both `enumerable` and
+ // `configurable`.
+ despriptor = { 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
+if (!Object.getOwnPropertyNames) {
+ Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
+ return Object.keys(object);
+ };
+}
+
+// ES5 15.2.3.5
+if (!Object.create) {
+ Object.create = function create(prototype, properties) {
+ var object;
+ if (prototype === null) {
+ object = { "__proto__": null };
+ } 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 (typeof properties !== "undefined")
+ Object.defineProperties(object, properties);
+ return object;
+ };
+}
+
+// ES5 15.2.3.6
+if (!Object.defineProperty) {
+ 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")
+ throw new TypeError(ERR_NON_OBJECT_TARGET + object);
+ if (typeof object !== "object" || object === null)
+ throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
+
+ // 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.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
+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
+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
+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
+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
+if (!Object.isSealed) {
+ Object.isSealed = function isSealed(object) {
+ return false;
+ };
+}
+
+// ES5 15.2.3.12
+if (!Object.isFrozen) {
+ Object.isFrozen = function isFrozen(object) {
+ return false;
+ };
+}
+
+// ES5 15.2.3.13
+if (!Object.isExtensible) {
+ Object.isExtensible = function isExtensible(object) {
+ return true;
+ };
+}
+
+// ES5 15.2.3.14
+// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
+if (!Object.keys) {
+
+ 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;
+ };
+
+}
+
+//
+// Date
+// ====
+//
+
+// ES5 15.9.5.43
+// Format a Date object as a string according to a subset of the ISO-8601 standard.
+// Useful in Atom, among other things.
+if (!Date.prototype.toISOString) {
+ Date.prototype.toISOString = function toISOString() {
+ return (
+ this.getUTCFullYear() + "-" +
+ (this.getUTCMonth() + 1) + "-" +
+ this.getUTCDate() + "T" +
+ this.getUTCHours() + ":" +
+ this.getUTCMinutes() + ":" +
+ this.getUTCSeconds() + "Z"
+ );
+ }
+}
+
+// ES5 15.9.4.4
+if (!Date.now) {
+ Date.now = function now() {
+ return new Date().getTime();
+ };
+}
+
+// ES5 15.9.5.44
+if (!Date.prototype.toJSON) {
+ Date.prototype.toJSON = function toJSON(key) {
+ // This function provides a String representation of a Date object for
+ // use by JSON.stringify (15.12.3). When the toJSON method is called
+ // with argument key, the following steps are taken:
+
+ // 1. Let O be the result of calling ToObject, giving it the this
+ // value as its argument.
+ // 2. Let tv be ToPrimitive(O, hint Number).
+ // 3. If tv is a Number and is not finite, return null.
+ // XXX
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
+ // O with argument "toISOString".
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
+ if (typeof this.toISOString !== "function")
+ throw new TypeError();
+ // 6. Return the result of calling the [[Call]] internal method of
+ // toISO with O as the this value and an empty argument list.
+ return this.toISOString();
+
+ // NOTE 1 The argument is ignored.
+
+ // NOTE 2 The toJSON function is intentionally generic; it does not
+ // require that its this value be a Date object. Therefore, it can be
+ // transferred to other kinds of objects for use as a method. However,
+ // it does require that any such object have a toISOString method. An
+ // object is free to use the argument key to filter its
+ // stringification.
+ };
+}
+
+// 15.9.4.2 Date.parse (string)
+// 15.9.1.15 Date Time String Format
+// Date.parse
+// based on work shared by Daniel Friesen (dantman)
+// http://gist.github.com/303249
+if (isNaN(Date.parse("T00:00"))) {
+ // XXX global assignment won't work in embeddings that use
+ // an alternate object for the context.
+ Date = (function(NativeDate) {
+
+ // Date.length === 7
+ var Date = function(Y, M, D, h, m, s, ms) {
+ var length = arguments.length;
+ if (this instanceof NativeDate) {
+ var date = length === 1 && String(Y) === Y ? // isString(Y)
+ // We explicitly pass it through parse:
+ new NativeDate(Date.parse(Y)) :
+ // We have to manually make calls depending on argument
+ // length here
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
+ length >= 4 ? new NativeDate(Y, M, D, h) :
+ length >= 3 ? new NativeDate(Y, M, D) :
+ length >= 2 ? new NativeDate(Y, M) :
+ length >= 1 ? new NativeDate(Y) :
+ new NativeDate();
+ // Prevent mixups with unfixed Date object
+ date.constructor = Date;
+ return date;
+ }
+ return NativeDate.apply(this, arguments);
+ };
+
+ // 15.9.1.15 Date Time String Format
+ var isoDateExpression = new RegExp("^" +
+ "(?:" + // optional year-month-day
+ "(" + // year capture
+ "(?:[+-]\\d\\d)?" + // 15.9.1.15.1 Extended years
+ "\\d\\d\\d\\d" + // four-digit year
+ ")" +
+ "(?:-" + // optional month-day
+ "(\\d\\d)" + // month capture
+ "(?:-" + // optional day
+ "(\\d\\d)" + // day capture
+ ")?" +
+ ")?" +
+ ")?" +
+ "(?:T" + // hour:minute:second.subsecond
+ "(\\d\\d)" + // hour capture
+ ":(\\d\\d)" + // minute capture
+ "(?::" + // optional :second.subsecond
+ "(\\d\\d)" + // second capture
+ "(?:\\.(\\d\\d\\d))?" + // milisecond capture
+ ")?" +
+ ")?" +
+ "(?:" + // time zone
+ "Z|" + // UTC capture
+ "([+-])(\\d\\d):(\\d\\d)" + // timezone offset
+ // capture sign, hour, minute
+ ")?" +
+ "$");
+
+ // Copy any custom methods a 3rd party library may have added
+ for (var key in NativeDate)
+ Date[key] = NativeDate[key];
+
+ // Copy "native" methods explicitly; they may be non-enumerable
+ Date.now = NativeDate.now;
+ Date.UTC = NativeDate.UTC;
+ Date.prototype = NativeDate.prototype;
+ Date.prototype.constructor = Date;
+
+ // Upgrade Date.parse to handle the ISO dates we use
+ // TODO review specification to ascertain whether it is
+ // necessary to implement partial ISO date strings.
+ Date.parse = function parse(string) {
+ var match = isoDateExpression.exec(string);
+ if (match) {
+ match.shift(); // kill match[0], the full match
+ // recognize times without dates before normalizing the
+ // numeric values, for later use
+ var timeOnly = match[0] === undefined;
+ // parse numerics
+ for (var i = 0; i < 10; i++) {
+ // skip + or - for the timezone offset
+ if (i === 7)
+ continue;
+ // Note: parseInt would read 0-prefix numbers as
+ // octal. Number constructor or unary + work better
+ // here:
+ match[i] = +(match[i] || (i < 3 ? 1 : 0));
+ // match[1] is the month. Months are 0-11 in JavaScript
+ // Date objects, but 1-12 in ISO notation, so we
+ // decrement.
+ if (i === 1)
+ match[i]--;
+ }
+ // if no year-month-date is provided, return a milisecond
+ // quantity instead of a UTC date number value.
+ if (timeOnly)
+ return ((match[3] * 60 + match[4]) * 60 + match[5]) * 1000 + match[6];
+
+ // account for an explicit time zone offset if provided
+ var offset = (match[8] * 60 + match[9]) * 60 * 1000;
+ if (match[6] === "-")
+ offset = -offset;
+
+ return NativeDate.UTC.apply(this, match.slice(0, 7)) + offset;
+ }
+ return NativeDate.parse.apply(this, arguments);
+ };
+
+ return Date;
+ })(Date);
+}
+
+//
+// String
+// ======
+//
+
+// ES5 15.5.4.20
+if (!String.prototype.trim) {
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
+ var trimBeginRegexp = /^\s\s*/;
+ var trimEndRegexp = /\s\s*$/;
+ String.prototype.trim = function trim() {
+ return String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
+ };
+}
+
+});
\ No newline at end of file
diff --git a/lib/ace/lib/keys.js b/ace/lib/keys.js
similarity index 68%
rename from lib/ace/lib/keys.js
rename to ace/lib/keys.js
index 465d4a8d..f6e9d0bc 100644
--- a/lib/ace/lib/keys.js
+++ b/ace/lib/keys.js
@@ -32,13 +32,10 @@ For more information about SproutCore, visit http://www.sproutcore.com
// Most of the following code is taken from SproutCore with a few changes.
define(function(require, exports, module) {
-"use strict";
-require("./fixoldbrowsers");
+var oop = require("ace/lib/oop");
-var oop = require("./oop");
-
-/*
+/**
* Helper functions and hashes for key handling.
*/
var Keys = (function() {
@@ -48,8 +45,8 @@ var Keys = (function() {
},
KEY_MODS: {
- "ctrl": 1, "alt": 2, "option" : 2, "shift": 4,
- "super": 8, "meta": 8, "command": 8, "cmd": 8
+ "ctrl": 1, "alt": 2, "option" : 2,
+ "shift": 4, "meta": 8, "command": 8
},
FUNCTION_KEYS : {
@@ -70,17 +67,6 @@ var Keys = (function() {
44 : "Print",
45 : "Insert",
46 : "Delete",
- 96 : "Numpad0",
- 97 : "Numpad1",
- 98 : "Numpad2",
- 99 : "Numpad3",
- 100: "Numpad4",
- 101: "Numpad5",
- 102: "Numpad6",
- 103: "Numpad7",
- 104: "Numpad8",
- 105: "Numpad9",
- '-13': "NumpadEnter",
112: "F1",
113: "F2",
114: "F3",
@@ -104,21 +90,14 @@ var Keys = (function() {
73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o',
80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
- 186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`',
- 219: '[', 220: '\\',221: ']', 222: '\''
+ 188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
+ 221: ']', 222: '\"'
}
};
// A reverse map of FUNCTION_KEYS
- var name, i;
for (i in ret.FUNCTION_KEYS) {
- name = ret.FUNCTION_KEYS[i].toLowerCase();
- ret[name] = parseInt(i, 10);
- }
-
- // A reverse map of PRINTABLE_KEYS
- for (i in ret.PRINTABLE_KEYS) {
- name = ret.PRINTABLE_KEYS[i].toLowerCase();
+ var name = ret.FUNCTION_KEYS[i].toUpperCase();
ret[name] = parseInt(i, 10);
}
@@ -128,36 +107,12 @@ var Keys = (function() {
oop.mixin(ret, ret.PRINTABLE_KEYS);
oop.mixin(ret, ret.FUNCTION_KEYS);
- // aliases
- ret.enter = ret["return"];
- ret.escape = ret.esc;
- ret.del = ret["delete"];
-
- // workaround for firefox bug
- ret[173] = '-';
-
- (function() {
- var mods = ["cmd", "ctrl", "alt", "shift"];
- for (var i = Math.pow(2, mods.length); i--;) {
- ret.KEY_MODS[i] = mods.filter(function(x) {
- return i & ret.KEY_MODS[x];
- }).join("-") + "-";
- }
- })();
-
- ret.KEY_MODS[0] = "";
- ret.KEY_MODS[-1] = "input-";
-
return ret;
})();
oop.mixin(exports, Keys);
exports.keyCodeToString = function(keyCode) {
- // Language-switching keystroke in Chrome/Linux emits keyCode 0.
- var keyString = Keys[keyCode];
- if (typeof keyString != "string")
- keyString = String.fromCharCode(keyCode);
- return keyString.toLowerCase();
-};
+ return (Keys[keyCode] || String.fromCharCode(keyCode)).toLowerCase();
+}
});
diff --git a/ace/lib/lang.js b/ace/lib/lang.js
new file mode 100644
index 00000000..a65f9a19
--- /dev/null
+++ b/ace/lib/lang.js
@@ -0,0 +1,150 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+exports.stringReverse = function(string) {
+ return string.split("").reverse().join("");
+};
+
+exports.stringRepeat = function (string, count) {
+ return new Array(count + 1).join(string);
+};
+
+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 (i=0, l=array.length; i
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+exports.inherits = (function() {
+ var tempCtor = function() {};
+ return function(ctor, superCtor) {
+ tempCtor.prototype = superCtor.prototype;
+ ctor.super_ = superCtor.prototype;
+ ctor.prototype = new tempCtor();
+ ctor.prototype.constructor = ctor;
+ }
+}());
+
+exports.mixin = function(obj, mixin) {
+ for (var key in mixin) {
+ obj[key] = mixin[key];
+ }
+};
+
+exports.implement = function(proto, mixin) {
+ exports.mixin(proto, mixin);
+};
+
+});
diff --git a/lib/ace/lib/regexp.js b/ace/lib/regexp.js
similarity index 90%
rename from lib/ace/lib/regexp.js
rename to ace/lib/regexp.js
index 369f74fc..399dcf9b 100644
--- a/lib/ace/lib/regexp.js
+++ b/ace/lib/regexp.js
@@ -1,16 +1,13 @@
-/*
- * Based on code from:
- *
- * XRegExp 1.5.0
- * (c) 2007-2010 Steven Levithan
- * MIT License
- *
- * 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";
+
+// Based on code from:
+//
+// XRegExp 1.5.0
+// (c) 2007-2010 Steven Levithan
+// MIT License
+//
+// Provides an augmented, extensible, cross-browser implementation of regular expressions,
+// including support for additional syntax, flags, and methods
//---------------------------------
// Private variables
@@ -30,9 +27,6 @@ define(function(require, exports, module) {
return !x.lastIndex;
}();
- if (compliantLastIndexIncrement && compliantExecNpcg)
- return;
-
//---------------------------------
// Overriden native methods
//---------------------------------
@@ -45,7 +39,7 @@ define(function(require, exports, module) {
RegExp.prototype.exec = function (str) {
var match = real.exec.apply(this, arguments),
name, r2;
- if ( typeof(str) == 'string' && match) {
+ if (match) {
// Fix browsers whose `exec` methods don't consistently return `undefined` for
// nonparticipating capturing groups
if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
@@ -98,7 +92,7 @@ define(function(require, exports, module) {
(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
@@ -108,6 +102,6 @@ define(function(require, exports, module) {
return i;
}
return -1;
- }
+ };
-});
+});
\ No newline at end of file
diff --git a/ace/lib/useragent.js b/ace/lib/useragent.js
new file mode 100644
index 00000000..708d576b
--- /dev/null
+++ b/ace/lib/useragent.js
@@ -0,0 +1,99 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
+var ua = navigator.userAgent;
+var av = navigator.appVersion;
+
+/** 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");
+
+exports.isIE = ! + "\v1";
+
+/** Is this Firefox or related? */
+exports.isGecko = exports.isMozilla = window.controllers && window.navigator.product === "Gecko";
+
+/** oldGecko == rev < 2.0 **/
+exports.isOldGecko = exports.isGecko && /rv\:1/.test(navigator.userAgent);
+
+/** 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;
+
+/**
+ * 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'];
+ }
+};
+
+});
diff --git a/ace/mode/behaviour.js b/ace/mode/behaviour.js
new file mode 100644
index 00000000..c30afbad
--- /dev/null
+++ b/ace/mode/behaviour.js
@@ -0,0 +1,97 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Chris Spencer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+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;
+});
\ No newline at end of file
diff --git a/ace/mode/behaviour/cstyle.js b/ace/mode/behaviour/cstyle.js
new file mode 100644
index 00000000..10bee574
--- /dev/null
+++ b/ace/mode/behaviour/cstyle.js
@@ -0,0 +1,228 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Chris Spencer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var Behaviour = require('ace/mode/behaviour').Behaviour;
+
+var CstyleBehaviour = function () {
+
+ this.add("braces", "insertion", function (state, action, editor, session, text) {
+ if (text == '{') {
+ var selection = editor.getSelectionRange();
+ var selected = session.doc.getTextRange(selection);
+ if (selected !== "") {
+ return {
+ text: '{' + selected + '}',
+ selection: false
+ }
+ } else {
+ return {
+ text: '{}',
+ selection: [1, 1]
+ }
+ }
+ } else if (text == '}') {
+ 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) {
+ return {
+ text: '',
+ selection: [1, 1]
+ }
+ }
+ }
+ } else if (text == "\n") {
+ var cursor = editor.getCursorPosition();
+ var line = session.doc.getLine(cursor.row);
+ 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 false;
+
+ var indent = this.getNextLineIndent(state, line.substring(0, line.length - 1), session.getTabString());
+ var next_indent = this.$getIndent(session.doc.getLine(openBracePos.row));
+
+ return {
+ text: '\n' + indent + '\n' + next_indent,
+ selection: [1, indent.length, 1, indent.length]
+ }
+ }
+ }
+ return false;
+ });
+
+ this.add("braces", "deletion", function (state, action, editor, session, range) {
+ var selected = session.doc.getTextRange(range);
+ if (!range.isMultiLine() && selected == '{') {
+ 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;
+ }
+ }
+ return false;
+ });
+
+ this.add("parens", "insertion", function (state, action, editor, session, text) {
+ if (text == '(') {
+ var selection = editor.getSelectionRange();
+ var selected = session.doc.getTextRange(selection);
+ if (selected !== "") {
+ return {
+ text: '(' + selected + ')',
+ selection: false
+ }
+ } else {
+ return {
+ text: '()',
+ selection: [1, 1]
+ }
+ }
+ } else if (text == ')') {
+ 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) {
+ return {
+ text: '',
+ selection: [1, 1]
+ }
+ }
+ }
+ }
+ return false;
+ });
+
+ this.add("parens", "deletion", function (state, action, editor, session, range) {
+ var selected = session.doc.getTextRange(range);
+ if (!range.isMultiLine() && selected == '(') {
+ 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;
+ }
+ }
+ return false;
+ });
+
+ this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
+ if (text == '"') {
+ var selection = editor.getSelectionRange();
+ var selected = session.doc.getTextRange(selection);
+ if (selected !== "") {
+ return {
+ text: '"' + selected + '"',
+ selection: false
+ }
+ } else {
+ var cursor = editor.getCursorPosition();
+ var line = session.doc.getLine(cursor.row);
+ var leftChar = line.substring(cursor.column-1, cursor.column);
+
+ // We're escaped.
+ if (leftChar == '\\') {
+ return false;
+ }
+
+ // Find what token we're inside.
+ var tokens = session.getTokens(selection.start.row, selection.start.row)[0].tokens;
+ var col = 0, token;
+ var quotepos = -1; // Track whether we're inside an open quote.
+
+ for (var x = 0; x < tokens.length; x++) {
+ token = tokens[x];
+ if (token.type == "string") {
+ quotepos = -1;
+ } else if (quotepos < 0) {
+ quotepos = token.value.indexOf('"');
+ }
+ if ((token.value.length + col) > selection.start.column) {
+ break;
+ }
+ col += tokens[x].value.length;
+ }
+
+ // Try and be smart about when we auto insert.
+ if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf('"') === token.value.length-1)))) {
+ return {
+ text: '""',
+ selection: [1,1]
+ }
+ } else if (token && token.type === "string") {
+ // Ignore input and move right one if we're typing over the closing quote.
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
+ if (rightChar == '"') {
+ return {
+ text: '',
+ selection: [1, 1]
+ }
+ }
+ }
+ }
+ }
+ return false;
+ });
+
+ this.add("string_dquotes", "deletion", function (state, action, editor, session, range) {
+ var selected = session.doc.getTextRange(range);
+ if (!range.isMultiLine() && selected == '"') {
+ 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;
+ }
+ }
+ return false;
+ });
+
+}
+oop.inherits(CstyleBehaviour, Behaviour);
+
+exports.CstyleBehaviour = CstyleBehaviour;
+});
\ No newline at end of file
diff --git a/ace/mode/behaviour/xml.js b/ace/mode/behaviour/xml.js
new file mode 100644
index 00000000..546f32a9
--- /dev/null
+++ b/ace/mode/behaviour/xml.js
@@ -0,0 +1,92 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Chris Spencer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var Behaviour = require('ace/mode/behaviour').Behaviour;
+var CstyleBehaviour = require('ace/mode/behaviour/cstyle').CstyleBehaviour;
+
+var XmlBehaviour = function () {
+
+ this.inherit(CstyleBehaviour, ["string_dquotes"]); // Get string behaviour
+
+ this.add("brackets", "insertion", function (state, action, editor, session, text) {
+ if (text == '<') {
+ var selection = editor.getSelectionRange();
+ var selected = session.doc.getTextRange(selection);
+ if (selected !== "") {
+ return false;
+ } else {
+ return {
+ text: '<>',
+ selection: [1, 1]
+ }
+ }
+ } else if (text == '>') {
+ var cursor = editor.getCursorPosition();
+ var line = session.doc.getLine(cursor.row);
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
+ if (rightChar == '>') { // need some kind of matching check here
+ return {
+ text: '',
+ selection: [1, 1]
+ }
+ }
+ } else if (text == "\n") {
+ var cursor = editor.getCursorPosition();
+ var line = session.doc.getLine(cursor.row);
+ var rightChars = line.substring(cursor.column, cursor.column + 2);
+ if (rightChars == '') {
+ var indent = this.$getIndent(session.doc.getLine(cursor.row)) + session.getTabString();
+ var next_indent = this.$getIndent(session.doc.getLine(cursor.row));
+
+ return {
+ text: '\n' + indent + '\n' + next_indent,
+ selection: [1, indent.length, 1, indent.length]
+ }
+ }
+ }
+ return false;
+ });
+
+}
+oop.inherits(XmlBehaviour, Behaviour);
+
+exports.XmlBehaviour = XmlBehaviour;
+});
\ No newline at end of file
diff --git a/ace/mode/c_cpp.js b/ace/mode/c_cpp.js
new file mode 100644
index 00000000..04081c9c
--- /dev/null
+++ b/ace/mode/c_cpp.js
@@ -0,0 +1,130 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Gastón Kleiman
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var TextMode = require("ace/mode/text").Mode;
+var Tokenizer = require("ace/tokenizer").Tokenizer;
+var c_cppHighlightRules = require("ace/mode/c_cpp_highlight_rules").c_cppHighlightRules;
+var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
+var Range = require("ace/range").Range;
+var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour;
+
+var Mode = function() {
+ this.$tokenizer = new Tokenizer(new c_cppHighlightRules().getRules());
+ this.$outdent = new MatchingBraceOutdent();
+ this.$behaviour = new CstyleBehaviour();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ this.toggleCommentLines = function(state, doc, startRow, endRow) {
+ var outdent = true;
+ var outentedRows = [];
+ var re = /^(\s*)\/\//;
+
+ for (var i=startRow; i<= endRow; i++) {
+ if (!re.test(doc.getLine(i))) {
+ outdent = false;
+ break;
+ }
+ }
+
+ if (outdent) {
+ var deleteRange = new Range(0, 0, 0, 0);
+ for (var i=startRow; i<= endRow; i++)
+ {
+ var line = doc.getLine(i);
+ var m = line.match(re);
+ deleteRange.start.row = i;
+ deleteRange.end.row = i;
+ deleteRange.end.column = m[0].length;
+ doc.replace(deleteRange, m[1]);
+ }
+ }
+ else {
+ doc.indentRows(startRow, endRow, "//");
+ }
+ };
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+
+ var tokenizedLine = this.$tokenizer.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);
+ };
+
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+});
diff --git a/ace/mode/c_cpp_highlight_rules.js b/ace/mode/c_cpp_highlight_rules.js
new file mode 100644
index 00000000..dcf80215
--- /dev/null
+++ b/ace/mode/c_cpp_highlight_rules.js
@@ -0,0 +1,176 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Gastón Kleiman
+ *
+ * Based on Bespin's C/C++ Syntax Plugin by Marc McIntyre.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var lang = require("ace/lib/lang");
+var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules;
+var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;
+
+var c_cppHighlightRules = function() {
+
+ var keywords = lang.arrayToMap(
+ ("and|double|not_eq|throw|and_eq|dynamic_cast|operator|true|" +
+ "asm|else|or|try|auto|enum|or_eq|typedef|bitand|explicit|private|" +
+ "typeid|bitor|extern|protected|typename|bool|false|public|union|" +
+ "break|float|register|unsigned|case|fro|reinterpret-cast|using|catch|" +
+ "friend|return|virtual|char|goto|short|void|class|if|signed|volatile|" +
+ "compl|inline|sizeof|wchar_t|const|int|static|while|const-cast|long|" +
+ "static_cast|xor|continue|mutable|struct|xor_eq|default|namespace|" +
+ "switch|delete|new|template|do|not|this|for").split("|")
+ );
+
+ var buildinConstants = lang.arrayToMap(
+ ("NULL").split("|")
+ );
+
+ // regexp must not have capturing parentheses. Use (?:) instead.
+ // regexps are ordered -> the first match is used
+
+ this.$rules = {
+ "start" : [
+ {
+ token : "comment",
+ regex : "\\/\\/.*$"
+ },
+ new DocCommentHighlightRules().getStartRule("doc-start"),
+ {
+ token : "comment", // multi line comment
+ merge : true,
+ regex : "\\/\\*",
+ next : "comment"
+ }, {
+ token : "string", // single line
+ regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
+ }, {
+ token : "string", // multi line string start
+ merge : true,
+ regex : '["].*\\\\$',
+ next : "qqstring"
+ }, {
+ token : "string", // single line
+ regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
+ }, {
+ token : "string", // multi line string start
+ merge : true,
+ regex : "['].*\\\\$",
+ next : "qstring"
+ }, {
+ token : "constant.numeric", // hex
+ regex : "0[xX][0-9a-fA-F]+\\b"
+ }, {
+ token : "constant.numeric", // float
+ regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
+ }, {
+ token : "constant", //
+ regex : "<[a-zA-Z0-9.]+>"
+ }, {
+ token : "keyword", // pre-compiler directivs
+ regex : "(?:#include|#pragma|#line|#define|#undef|#ifdef|#else|#elif|#endif|#ifndef)"
+ }, {
+ token : function(value) {
+ if (value == "this")
+ return "variable.language";
+ else if (keywords.hasOwnProperty(value))
+ return "keyword";
+ else if (buildinConstants.hasOwnProperty(value))
+ return "constant.language";
+ else
+ return "identifier";
+ },
+ regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
+ }, {
+ token : "keyword.operator",
+ regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"
+ }, {
+ token : "lparen",
+ regex : "[[({]"
+ }, {
+ token : "rparen",
+ regex : "[\\])}]"
+ }, {
+ token : "text",
+ regex : "\\s+"
+ }
+ ],
+ "comment" : [
+ {
+ token : "comment", // closing comment
+ regex : ".*?\\*\\/",
+ next : "start"
+ }, {
+ token : "comment", // comment spanning whole line
+ merge : true,
+ regex : ".+"
+ }
+ ],
+ "qqstring" : [
+ {
+ token : "string",
+ regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"',
+ next : "start"
+ }, {
+ token : "string",
+ merge : true,
+ regex : '.+'
+ }
+ ],
+ "qstring" : [
+ {
+ token : "string",
+ regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'",
+ next : "start"
+ }, {
+ token : "string",
+ merge : true,
+ regex : '.+'
+ }
+ ]
+ };
+
+ this.embedRules(DocCommentHighlightRules, "doc-",
+ [ new DocCommentHighlightRules().getEndRule("start") ]);
+};
+
+oop.inherits(c_cppHighlightRules, TextHighlightRules);
+
+exports.c_cppHighlightRules = c_cppHighlightRules;
+});
diff --git a/ace/mode/clojure.js b/ace/mode/clojure.js
new file mode 100644
index 00000000..3bd8127f
--- /dev/null
+++ b/ace/mode/clojure.js
@@ -0,0 +1,123 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Shlomo Zalman Heigh
+ * Carin Meier
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var TextMode = require("ace/mode/text").Mode;
+var Tokenizer = require("ace/tokenizer").Tokenizer;
+var ClojureHighlightRules = require("ace/mode/clojure_highlight_rules").ClojureHighlightRules;
+var MatchingParensOutdent = require("ace/mode/matching_parens_outdent").MatchingParensOutdent;
+var Range = require("ace/range").Range;
+
+var Mode = function() {
+ this.$tokenizer = new Tokenizer(new ClojureHighlightRules().getRules());
+ this.$outdent = new MatchingParensOutdent();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ this.toggleCommentLines = function(state, doc, startRow, endRow) {
+ var outdent = true;
+ var outentedRows = [];
+ var re = /^(\s*)#/;
+
+ for (var i=startRow; i<= endRow; i++) {
+ if (!re.test(doc.getLine(i))) {
+ outdent = false;
+ break;
+ }
+ }
+
+ if (outdent) {
+ var deleteRange = new Range(0, 0, 0, 0);
+ for (var i=startRow; i<= endRow; i++)
+ {
+ var line = doc.getLine(i);
+ var m = line.match(re);
+ deleteRange.start.row = i;
+ deleteRange.end.row = i;
+ deleteRange.end.column = m[0].length;
+ doc.replace(deleteRange, m[1]);
+ }
+ }
+ else {
+ doc.indentRows(startRow, endRow, ";");
+ }
+ };
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+ var startingIndent = indent;
+
+ var tokenizedLine = this.$tokenizer.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(/[\(\[]/);
+ if (match) {
+ indent += " ";
+ }
+ match = line.match(/[\)]/);
+ if (match) {
+ 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);
+ };
+
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+});
diff --git a/ace/mode/clojure_highlight_rules.js b/ace/mode/clojure_highlight_rules.js
new file mode 100644
index 00000000..5ea1087e
--- /dev/null
+++ b/ace/mode/clojure_highlight_rules.js
@@ -0,0 +1,219 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ * Shlomo Zalman Heigh
+ * Carin Meier
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var lang = require("ace/lib/lang");
+var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;
+
+
+
+var ClojureHighlightRules = function() {
+
+ var builtinFunctions = lang.arrayToMap(
+ ('* *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* ' +
+ '*command-line-args* *compile-files* *compile-path* *e *err* *file* ' +
+ '*flush-on-newline* *in* *macro-meta* *math-context* *ns* *out* ' +
+ '*print-dup* *print-length* *print-level* *print-meta* *print-readably* ' +
+ '*read-eval* *source-path* *use-context-classloader* ' +
+ '*warn-on-reflection* + - -> -> ->> ->> .. / < < <= <= = ' +
+ '== > > >= >= accessor aclone ' +
+ 'add-classpath add-watch agent agent-errors aget alength alias all-ns ' +
+ 'alter alter-meta! alter-var-root amap ancestors and apply areduce ' +
+ 'array-map aset aset-boolean aset-byte aset-char aset-double aset-float ' +
+ 'aset-int aset-long aset-short assert assoc assoc! assoc-in associative? ' +
+ 'atom await await-for await1 bases bean bigdec bigint binding bit-and ' +
+ 'bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left ' +
+ 'bit-shift-right bit-test bit-xor boolean boolean-array booleans ' +
+ 'bound-fn bound-fn* butlast byte byte-array bytes cast char char-array ' +
+ 'char-escape-string char-name-string char? chars chunk chunk-append ' +
+ 'chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? ' +
+ 'class class? clear-agent-errors clojure-version coll? comment commute ' +
+ 'comp comparator compare compare-and-set! compile complement concat cond ' +
+ 'condp conj conj! cons constantly construct-proxy contains? count ' +
+ 'counted? create-ns create-struct cycle dec decimal? declare definline ' +
+ 'defmacro defmethod defmulti defn defn- defonce defstruct delay delay? ' +
+ 'deliver deref derive descendants destructure disj disj! dissoc dissoc! ' +
+ 'distinct distinct? doall doc dorun doseq dosync dotimes doto double ' +
+ 'double-array doubles drop drop-last drop-while empty empty? ensure ' +
+ 'enumeration-seq eval even? every? false? ffirst file-seq filter find ' +
+ 'find-doc find-ns find-var first float float-array float? floats flush ' +
+ 'fn fn? fnext for force format future future-call future-cancel ' +
+ 'future-cancelled? future-done? future? gen-class gen-interface gensym ' +
+ 'get get-in get-method get-proxy-class get-thread-bindings get-validator ' +
+ 'hash hash-map hash-set identical? identity if-let if-not ifn? import ' +
+ 'in-ns inc init-proxy instance? int int-array integer? interleave intern ' +
+ 'interpose into into-array ints io! isa? iterate iterator-seq juxt key ' +
+ 'keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list ' +
+ 'list* list? load load-file load-reader load-string loaded-libs locking ' +
+ 'long long-array longs loop macroexpand macroexpand-1 make-array ' +
+ 'make-hierarchy map map? mapcat max max-key memfn memoize merge ' +
+ 'merge-with meta method-sig methods min min-key mod name namespace neg? ' +
+ 'newline next nfirst nil? nnext not not-any? not-empty not-every? not= ' +
+ 'ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ' +
+ 'ns-refers ns-resolve ns-unalias ns-unmap nth nthnext num number? odd? ' +
+ 'or parents partial partition pcalls peek persistent! pmap pop pop! ' +
+ 'pop-thread-bindings pos? pr pr-str prefer-method prefers ' +
+ 'primitives-classnames print print-ctor print-doc print-dup print-method ' +
+ 'print-namespace-doc print-simple print-special-doc print-str printf ' +
+ 'println println-str prn prn-str promise proxy proxy-call-with-super ' +
+ 'proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot ' +
+ 'rand rand-int range ratio? rational? rationalize re-find re-groups ' +
+ 're-matcher re-matches re-pattern re-seq read read-line read-string ' +
+ 'reduce ref ref-history-count ref-max-history ref-min-history ref-set ' +
+ 'refer refer-clojure release-pending-sends rem remove remove-method ' +
+ 'remove-ns remove-watch repeat repeatedly replace replicate require ' +
+ 'reset! reset-meta! resolve rest resultset-seq reverse reversible? rseq ' +
+ 'rsubseq second select-keys send send-off seq seq? seque sequence ' +
+ 'sequential? set set-validator! set? short short-array shorts ' +
+ 'shutdown-agents slurp some sort sort-by sorted-map sorted-map-by ' +
+ 'sorted-set sorted-set-by sorted? special-form-anchor special-symbol? ' +
+ 'split-at split-with str stream? string? struct struct-map subs subseq ' +
+ 'subvec supers swap! symbol symbol? sync syntax-symbol-anchor take ' +
+ 'take-last take-nth take-while test the-ns time to-array to-array-2d ' +
+ 'trampoline transient tree-seq true? type unchecked-add unchecked-dec ' +
+ 'unchecked-divide unchecked-inc unchecked-multiply unchecked-negate ' +
+ 'unchecked-remainder unchecked-subtract underive unquote ' +
+ 'unquote-splicing update-in update-proxy use val vals var-get var-set ' +
+ 'var? vary-meta vec vector vector? when when-first when-let when-not ' +
+ 'while with-bindings with-bindings* with-in-str with-loading-context ' +
+ 'with-local-vars with-meta with-open with-out-str with-precision xml-seq ' +
+ 'zero? zipmap ').split(" ")
+ );
+
+ var keywords = lang.arrayToMap(
+ ('def do fn if let loop monitor-enter monitor-exit new quote recur set! ' +
+ 'throw try var').split(" ")
+ );
+
+ var buildinConstants = lang.arrayToMap(
+ ("true false nil").split(" ")
+ );
+
+
+ // 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 : "^\=begin$",
+ next : "comment"
+ }, {
+ token : "keyword", //parens
+ regex : "[\\(|\\)]"
+ }, {
+ token : "keyword", //lists
+ regex : "[\\'\\(]"
+ }, {
+ token : "keyword", //vectors
+ regex : "[\\[|\\]]"
+ }, {
+ token : "keyword", //sets and maps
+ regex : "[\\{|\\}|\\#\\{|\\#\\}]"
+ }, {
+ token : "keyword", // ampersands
+ regex : '[\\&]'
+ }, {
+ token : "keyword", // metadata
+ regex : '[\\#\\^\\{]'
+ }, {
+ token : "keyword", // anonymous fn syntactic sugar
+ regex : '[\\%]'
+ }, {
+ token : "keyword", // deref reader macro
+ 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",
+ regex : '[!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+||=|!=|<=|>=|<>|<|>|!|&&]'
+ }, {
+ token : function(value) {
+ if (keywords.hasOwnProperty(value))
+ return "keyword";
+ else if (buildinConstants.hasOwnProperty(value))
+ return "constant.language";
+ else if (builtinFunctions.hasOwnProperty(value))
+ return "support.function";
+ else
+ return "identifier";
+ },
+ // TODO: Unicode escape sequences
+ // TODO: Unicode identifiers
+ regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
+ }, {
+ token : "string", // single line
+ regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
+ }, {
+ token : "string", // symbol
+ regex : "[:](?:[a-zA-Z]|\d)+"
+ }, {
+ token : "string.regexp", //Regular Expressions
+ regex : '/#"(?:\.|(\\\")|[^\""\n])*"/g'
+ }
+
+ ],
+ "comment" : [
+ {
+ token : "comment", // closing comment
+ regex : "^\=end$",
+ next : "start"
+ }, {
+ token : "comment", // comment spanning whole line
+ merge : true,
+ regex : ".+"
+ }
+ ]
+ };
+};
+
+oop.inherits(ClojureHighlightRules, TextHighlightRules);
+
+exports.ClojureHighlightRules = ClojureHighlightRules;
+});
diff --git a/ace/mode/coffee.js b/ace/mode/coffee.js
new file mode 100644
index 00000000..c632807a
--- /dev/null
+++ b/ace/mode/coffee.js
@@ -0,0 +1,125 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Satoshi Murakami
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var Tokenizer = require("ace/tokenizer").Tokenizer;
+var Rules = require("ace/mode/coffee_highlight_rules").CoffeeHighlightRules;
+var Outdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
+var Range = require("ace/range").Range;
+var TextMode = require("ace/mode/text").Mode;
+var WorkerClient = require("ace/worker/worker_client").WorkerClient;
+var oop = require("ace/lib/oop");
+
+function Mode() {
+ this.$tokenizer = new Tokenizer(new Rules().getRules());
+ this.$outdent = new Outdent();
+}
+
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ var indenter = /(?:[({[=:]|[-=]>|\b(?:else|switch|try|catch(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$/;
+ var commentLine = /^(\s*)#/;
+ var hereComment = /^\s*###(?!#)/;
+ var indentation = /^\s*/;
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+ var tokens = this.$tokenizer.getLineTokens(line, state).tokens;
+
+ if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') &&
+ state === 'start' && indenter.test(line))
+ indent += tab;
+ return indent;
+ };
+
+ this.toggleCommentLines = function(state, doc, startRow, endRow){
+ console.log("toggle");
+ var range = new Range(0, 0, 0, 0);
+ for (var i = startRow; i <= endRow; ++i) {
+ var line = doc.getLine(i);
+ if (hereComment.test(line))
+ continue;
+
+ if (commentLine.test(line))
+ line = line.replace(commentLine, '$1');
+ else
+ line = line.replace(indentation, '$');
+
+ range.end.row = range.start.row = i;
+ range.end.column = line.length + 1;
+ doc.replace(range, line);
+ }
+ };
+
+ 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 doc = session.getDocument();
+ var worker = new WorkerClient(["ace"], "worker-coffee.js", "ace/mode/coffee_worker", "Worker");
+ worker.call("setValue", [doc.getValue()]);
+
+ doc.on("change", function(e) {
+ e.range = {
+ start: e.data.range.start,
+ end: e.data.range.end
+ };
+ worker.emit("change", e);
+ });
+
+ worker.on("error", function(e) {
+ session.setAnnotations([e.data]);
+ });
+
+ worker.on("ok", function(e) {
+ session.clearAnnotations();
+ });
+ };
+
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+
+});
\ No newline at end of file
diff --git a/ace/mode/coffee/coffee-script.js b/ace/mode/coffee/coffee-script.js
new file mode 100644
index 00000000..f7ca2dc3
--- /dev/null
+++ b/ace/mode/coffee/coffee-script.js
@@ -0,0 +1,63 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+ var Lexer = require("ace/mode/coffee/lexer").Lexer;
+ var parser = require("ace/mode/coffee/parser");
+
+ var lexer = new Lexer();
+ parser.lexer = {
+ lex: function() {
+ var tag, _ref2;
+ _ref2 = this.tokens[this.pos++] || [''], tag = _ref2[0], this.yytext = _ref2[1], this.yylineno = _ref2[2];
+ return tag;
+ },
+ setInput: function(tokens) {
+ this.tokens = tokens;
+ return this.pos = 0;
+ },
+ upcomingInput: function() {
+ return "";
+ }
+ };
+ parser.yy = require('ace/mode/coffee/nodes');
+
+ exports.parse = function(code) {
+ return parser.parse(lexer.tokenize(code));
+ };
+});
\ No newline at end of file
diff --git a/ace/mode/coffee/helpers.js b/ace/mode/coffee/helpers.js
new file mode 100644
index 00000000..c03611e2
--- /dev/null
+++ b/ace/mode/coffee/helpers.js
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2011 Jeremy Ashkenas
+ *
+ * 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.
+ */
+
+define(function(require, exports, module) {
+
+ var extend, flatten;
+ exports.starts = function(string, literal, start) {
+ return literal === string.substr(start, literal.length);
+ };
+ exports.ends = function(string, literal, back) {
+ var len;
+ len = literal.length;
+ return literal === string.substr(string.length - len - (back || 0), len);
+ };
+ exports.compact = function(array) {
+ var item, _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
+ item = array[_i];
+ if (item) {
+ _results.push(item);
+ }
+ }
+ return _results;
+ };
+ exports.count = function(string, substr) {
+ var num, pos;
+ num = pos = 0;
+ if (!substr.length) {
+ return 1 / 0;
+ }
+ while (pos = 1 + string.indexOf(substr, pos)) {
+ num++;
+ }
+ return num;
+ };
+ exports.merge = function(options, overrides) {
+ return extend(extend({}, options), overrides);
+ };
+ extend = exports.extend = function(object, properties) {
+ var key, val;
+ for (key in properties) {
+ val = properties[key];
+ object[key] = val;
+ }
+ return object;
+ };
+ exports.flatten = flatten = function(array) {
+ var element, flattened, _i, _len;
+ flattened = [];
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
+ element = array[_i];
+ if (element instanceof Array) {
+ flattened = flattened.concat(flatten(element));
+ } else {
+ flattened.push(element);
+ }
+ }
+ return flattened;
+ };
+ exports.del = function(obj, key) {
+ var val;
+ val = obj[key];
+ delete obj[key];
+ return val;
+ };
+ exports.last = function(array, back) {
+ return array[array.length - (back || 0) - 1];
+ };
+});
diff --git a/lib/ace/mode/coffee/lexer.js b/ace/mode/coffee/lexer.js
similarity index 51%
rename from lib/ace/mode/coffee/lexer.js
rename to ace/mode/coffee/lexer.js
index 05d85236..ab15ec43 100644
--- a/lib/ace/mode/coffee/lexer.js
+++ b/ace/mode/coffee/lexer.js
@@ -1,6 +1,6 @@
/**
- * Copyright (c) 2009-2013 Jeremy Ashkenas
- *
+ * Copyright (c) 2011 Jeremy Ashkenas
+ *
* 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
@@ -21,84 +21,60 @@
* 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.
- *
*/
define(function(require, exports, module) {
-// Generated by CoffeeScript 1.6.3
-
- var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
-
- _ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
-
- _ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, repeat = _ref1.repeat, invertLiterate = _ref1.invertLiterate, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
-
+
+ var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref;
+ var __indexOf = Array.prototype.indexOf || function(item) {
+ for (var i = 0, l = this.length; i < l; i++) {
+ if (this[i] === item) return i;
+ }
+ return -1;
+ };
+ Rewriter = require('ace/mode/coffee/rewriter').Rewriter;
+ _ref = require('ace/mode/coffee/helpers'), count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
exports.Lexer = Lexer = (function() {
function Lexer() {}
-
Lexer.prototype.tokenize = function(code, opts) {
- var consumed, i, tag, _ref2;
+ var i;
if (opts == null) {
opts = {};
}
- this.literate = opts.literate;
+ if (WHITESPACE.test(code)) {
+ code = "\n" + code;
+ }
+ code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
+ this.code = code;
+ this.line = opts.line || 0;
this.indent = 0;
- this.baseIndent = 0;
this.indebt = 0;
this.outdebt = 0;
this.indents = [];
- this.ends = [];
this.tokens = [];
- this.chunkLine = opts.line || 0;
- this.chunkColumn = opts.column || 0;
- code = this.clean(code);
i = 0;
while (this.chunk = code.slice(i)) {
- consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
- _ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = _ref2[0], this.chunkColumn = _ref2[1];
- i += consumed;
+ i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
}
this.closeIndentation();
- if (tag = this.ends.pop()) {
- this.error("missing " + tag);
- }
if (opts.rewrite === false) {
return this.tokens;
}
return (new Rewriter).rewrite(this.tokens);
};
-
- Lexer.prototype.clean = function(code) {
- if (code.charCodeAt(0) === BOM) {
- code = code.slice(1);
- }
- code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
- if (WHITESPACE.test(code)) {
- code = "\n" + code;
- this.chunkLine--;
- }
- if (this.literate) {
- code = invertLiterate(code);
- }
- return code;
- };
-
Lexer.prototype.identifierToken = function() {
- var colon, colonOffset, forcedIdentifier, id, idLength, input, match, poppedToken, prev, tag, tagToken, _ref2, _ref3, _ref4;
+ var colon, forcedIdentifier, id, input, match, prev, tag, _ref2, _ref3;
if (!(match = IDENTIFIER.exec(this.chunk))) {
return 0;
}
input = match[0], id = match[1], colon = match[2];
- idLength = id.length;
- poppedToken = void 0;
if (id === 'own' && this.tag() === 'FOR') {
this.token('OWN', id);
return id.length;
}
- forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::' || _ref2 === '?::') || !prev.spaced && prev[0] === '@');
+ forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::') || !prev.spaced && prev[0] === '@');
tag = 'IDENTIFIER';
- if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
+ if (__indexOf.call(JS_KEYWORDS, id) >= 0 || !forcedIdentifier && __indexOf.call(COFFEE_KEYWORDS, id) >= 0) {
tag = id.toUpperCase();
if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) {
tag = 'LEADING_WHEN';
@@ -115,7 +91,7 @@ define(function(require, exports, module) {
} else {
tag = 'RELATION';
if (this.value() === '!') {
- poppedToken = this.tokens.pop();
+ this.tokens.pop();
id = '!' + id;
}
}
@@ -127,7 +103,7 @@ define(function(require, exports, module) {
id = new String(id);
id.reserved = true;
} else if (__indexOf.call(RESERVED, id) >= 0) {
- this.error("reserved word \"" + id + "\"");
+ this.identifierError(id);
}
}
if (!forcedIdentifier) {
@@ -146,79 +122,58 @@ define(function(require, exports, module) {
return 'LOGIC';
case 'true':
case 'false':
+ case 'null':
+ case 'undefined':
return 'BOOL';
case 'break':
case 'continue':
+ case 'debugger':
return 'STATEMENT';
default:
return tag;
}
})();
}
- tagToken = this.token(tag, id, 0, idLength);
- if (poppedToken) {
- _ref4 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = _ref4[0], tagToken[2].first_column = _ref4[1];
- }
+ this.token(tag, id);
if (colon) {
- colonOffset = input.lastIndexOf(':');
- this.token(':', ':', colonOffset, colon.length);
+ this.token(':', ':');
}
return input.length;
};
-
Lexer.prototype.numberToken = function() {
- var binaryLiteral, lexedLength, match, number, octalLiteral;
+ var match, number;
if (!(match = NUMBER.exec(this.chunk))) {
return 0;
}
number = match[0];
- if (/^0[BOX]/.test(number)) {
- this.error("radix prefix '" + number + "' must be lowercase");
- } else if (/E/.test(number) && !/^0x/.test(number)) {
- this.error("exponential notation '" + number + "' must be indicated with a lowercase 'e'");
- } else if (/^0\d*[89]/.test(number)) {
- this.error("decimal literal '" + number + "' must not be prefixed with '0'");
- } else if (/^0\d+/.test(number)) {
- this.error("octal literal '" + number + "' must be prefixed with '0o'");
- }
- lexedLength = number.length;
- if (octalLiteral = /^0o([0-7]+)/.exec(number)) {
- number = '0x' + parseInt(octalLiteral[1], 8).toString(16);
- }
- if (binaryLiteral = /^0b([01]+)/.exec(number)) {
- number = '0x' + parseInt(binaryLiteral[1], 2).toString(16);
- }
- this.token('NUMBER', number, 0, lexedLength);
- return lexedLength;
+ this.token('NUMBER', number);
+ return number.length;
};
-
Lexer.prototype.stringToken = function() {
- var octalEsc, quote, string, trimmed;
- switch (quote = this.chunk.charAt(0)) {
+ var match, string;
+ switch (this.chunk.charAt(0)) {
case "'":
- string = SIMPLESTR.exec(this.chunk)[0];
+ if (!(match = SIMPLESTR.exec(this.chunk))) {
+ return 0;
+ }
+ this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n'));
break;
case '"':
- string = this.balancedString(this.chunk, '"');
- }
- if (!string) {
- return 0;
- }
- trimmed = this.removeNewlines(string.slice(1, -1));
- if (quote === '"' && 0 < string.indexOf('#{', 1)) {
- this.interpolateString(trimmed, {
- strOffset: 1,
- lexedLength: string.length
- });
- } else {
- this.token('STRING', quote + this.escapeLines(trimmed) + quote, 0, string.length);
- }
- if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) {
- this.error("octal escape sequences " + string + " are not allowed");
+ if (!(string = this.balancedString(this.chunk, '"'))) {
+ return 0;
+ }
+ if (0 < string.indexOf('#{', 1)) {
+ this.interpolateString(string.slice(1, -1));
+ } else {
+ this.token('STRING', this.escapeLines(string));
+ }
+ break;
+ default:
+ return 0;
}
+ this.line += count(string, '\n');
return string.length;
};
-
Lexer.prototype.heredocToken = function() {
var doc, heredoc, match, quote;
if (!(match = HEREDOC.exec(this.chunk))) {
@@ -232,16 +187,14 @@ define(function(require, exports, module) {
});
if (quote === '"' && 0 <= doc.indexOf('#{')) {
this.interpolateString(doc, {
- heredoc: true,
- strOffset: 3,
- lexedLength: heredoc.length
+ heredoc: true
});
} else {
- this.token('STRING', this.makeString(doc, quote, true), 0, heredoc.length);
+ this.token('STRING', this.makeString(doc, quote, true));
}
+ this.line += count(heredoc, '\n');
return heredoc.length;
};
-
Lexer.prototype.commentToken = function() {
var comment, here, match;
if (!(match = this.chunk.match(COMMENT))) {
@@ -251,29 +204,29 @@ define(function(require, exports, module) {
if (here) {
this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
herecomment: true,
- indent: repeat(' ', this.indent)
- }), 0, comment.length);
+ indent: Array(this.indent + 1).join(' ')
+ }));
+ this.token('TERMINATOR', '\n');
}
+ this.line += count(comment, '\n');
return comment.length;
};
-
Lexer.prototype.jsToken = function() {
var match, script;
if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
return 0;
}
- this.token('JS', (script = match[0]).slice(1, -1), 0, script.length);
+ this.token('JS', (script = match[0]).slice(1, -1));
return script.length;
};
-
Lexer.prototype.regexToken = function() {
- var flags, length, match, prev, regex, _ref2, _ref3;
+ var match, prev, regex, _ref2;
if (this.chunk.charAt(0) !== '/') {
return 0;
}
if (match = HEREGEX.exec(this.chunk)) {
- length = this.heregexToken(match);
- return length;
+ this.line += count(match[0], '\n');
+ return this.heregexToken(match);
}
prev = last(this.tokens);
if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) {
@@ -282,84 +235,63 @@ define(function(require, exports, module) {
if (!(match = REGEX.exec(this.chunk))) {
return 0;
}
- _ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2];
- if (regex.slice(0, 2) === '/*') {
- this.error('regular expressions cannot begin with `*`');
- }
- if (regex === '//') {
- regex = '/(?:)/';
- }
- this.token('REGEX', "" + regex + flags, 0, match.length);
- return match.length;
+ regex = match[0];
+ this.token('REGEX', regex === '//' ? '/(?:)/' : regex);
+ return regex.length;
};
-
Lexer.prototype.heregexToken = function(match) {
- var body, flags, flagsOffset, heregex, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
+ var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4, _ref5;
heregex = match[0], body = match[1], flags = match[2];
if (0 > body.indexOf('#{')) {
- re = this.escapeLines(body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/'), true);
- if (re.match(/^\*/)) {
- this.error('regular expressions cannot begin with `*`');
- }
- this.token('REGEX', "/" + (re || '(?:)') + "/" + flags, 0, heregex.length);
+ re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
+ this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
return heregex.length;
}
- this.token('IDENTIFIER', 'RegExp', 0, 0);
- this.token('CALL_START', '(', 0, 0);
+ this.token('IDENTIFIER', 'RegExp');
+ this.tokens.push(['CALL_START', '(']);
tokens = [];
_ref2 = this.interpolateString(body, {
regex: true
});
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- token = _ref2[_i];
- tag = token[0], value = token[1];
+ _ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1];
if (tag === 'TOKENS') {
tokens.push.apply(tokens, value);
- } else if (tag === 'NEOSTRING') {
- if (!(value = value.replace(HEREGEX_OMIT, '$1$2'))) {
+ } else {
+ if (!(value = value.replace(HEREGEX_OMIT, ''))) {
continue;
}
value = value.replace(/\\/g, '\\\\');
- token[0] = 'STRING';
- token[1] = this.makeString(value, '"', true);
- tokens.push(token);
- } else {
- this.error("Unexpected " + tag);
+ tokens.push(['STRING', this.makeString(value, '"', true)]);
}
- prev = last(this.tokens);
- plusToken = ['+', '+'];
- plusToken[2] = prev[2];
- tokens.push(plusToken);
+ tokens.push(['+', '+']);
}
tokens.pop();
- if (((_ref3 = tokens[0]) != null ? _ref3[0] : void 0) !== 'STRING') {
- this.token('STRING', '""', 0, 0);
- this.token('+', '+', 0, 0);
+ if (((_ref4 = tokens[0]) != null ? _ref4[0] : void 0) !== 'STRING') {
+ this.tokens.push(['STRING', '""'], ['+', '+']);
}
- (_ref4 = this.tokens).push.apply(_ref4, tokens);
+ (_ref5 = this.tokens).push.apply(_ref5, tokens);
if (flags) {
- flagsOffset = heregex.lastIndexOf(flags);
- this.token(',', ',', flagsOffset, 0);
- this.token('STRING', '"' + flags + '"', flagsOffset, flags.length);
+ this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
}
- this.token(')', ')', heregex.length - 1, 0);
+ this.token(')', ')');
return heregex.length;
};
-
Lexer.prototype.lineToken = function() {
- var diff, indent, match, noNewlines, size;
+ var diff, indent, match, noNewlines, prev, size;
if (!(match = MULTI_DENT.exec(this.chunk))) {
return 0;
}
indent = match[0];
- this.seenFor = false;
+ this.line += count(indent, '\n');
+ prev = last(this.tokens, 1);
size = indent.length - 1 - indent.lastIndexOf('\n');
noNewlines = this.unfinished();
if (size - this.indebt === this.indent) {
if (noNewlines) {
this.suppressNewlines();
} else {
- this.newlineToken(0);
+ this.newlineToken();
}
return indent.length;
}
@@ -369,26 +301,18 @@ define(function(require, exports, module) {
this.suppressNewlines();
return indent.length;
}
- if (!this.tokens.length) {
- this.baseIndent = this.indent = size;
- return indent.length;
- }
diff = size - this.indent + this.outdebt;
- this.token('INDENT', diff, indent.length - size, size);
+ this.token('INDENT', diff);
this.indents.push(diff);
- this.ends.push('OUTDENT');
this.outdebt = this.indebt = 0;
- } else if (size < this.baseIndent) {
- this.error('missing indentation', indent.length);
} else {
this.indebt = 0;
- this.outdentToken(this.indent - size, noNewlines, indent.length);
+ this.outdentToken(this.indent - size, noNewlines);
}
this.indent = size;
return indent.length;
};
-
- Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) {
+ Lexer.prototype.outdentToken = function(moveOut, noNewlines, close) {
var dent, len;
while (moveOut > 0) {
len = this.indents.length - 1;
@@ -401,25 +325,20 @@ define(function(require, exports, module) {
this.outdebt -= this.indents[len];
moveOut -= this.indents[len];
} else {
- dent = this.indents.pop() + this.outdebt;
+ dent = this.indents.pop() - this.outdebt;
moveOut -= dent;
this.outdebt = 0;
- this.pair('OUTDENT');
- this.token('OUTDENT', dent, 0, outdentLength);
+ this.token('OUTDENT', dent);
}
}
if (dent) {
this.outdebt -= moveOut;
}
- while (this.value() === ';') {
- this.tokens.pop();
- }
if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
- this.token('TERMINATOR', '\n', outdentLength, 0);
+ this.token('TERMINATOR', '\n');
}
return this;
};
-
Lexer.prototype.whitespaceToken = function() {
var match, nline, prev;
if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) {
@@ -435,24 +354,18 @@ define(function(require, exports, module) {
return 0;
}
};
-
- Lexer.prototype.newlineToken = function(offset) {
- while (this.value() === ';') {
- this.tokens.pop();
- }
+ Lexer.prototype.newlineToken = function() {
if (this.tag() !== 'TERMINATOR') {
- this.token('TERMINATOR', '\n', offset, 0);
+ this.token('TERMINATOR', '\n');
}
return this;
};
-
Lexer.prototype.suppressNewlines = function() {
if (this.value() === '\\') {
this.tokens.pop();
}
return this;
};
-
Lexer.prototype.literalToken = function() {
var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5;
if (match = OPERATOR.exec(this.chunk)) {
@@ -467,7 +380,7 @@ define(function(require, exports, module) {
prev = last(this.tokens);
if (value === '=' && prev) {
if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) {
- this.error("reserved word \"" + (this.value()) + "\" can't be assigned");
+ this.assignmentError();
}
if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') {
prev[0] = 'COMPOUND_ASSIGN';
@@ -476,7 +389,6 @@ define(function(require, exports, module) {
}
}
if (value === ';') {
- this.seenFor = false;
tag = 'TERMINATOR';
} else if (__indexOf.call(MATH, value) >= 0) {
tag = 'MATH';
@@ -501,32 +413,23 @@ define(function(require, exports, module) {
switch (prev[0]) {
case '?':
prev[0] = 'INDEX_SOAK';
+ break;
+ case '::':
+ prev[0] = 'INDEX_PROTO';
}
}
}
- switch (value) {
- case '(':
- case '{':
- case '[':
- this.ends.push(INVERSES[value]);
- break;
- case ')':
- case '}':
- case ']':
- this.pair(value);
- }
this.token(tag, value);
return value.length;
};
-
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
var attempt, herecomment, indent, match, _ref2;
indent = options.indent, herecomment = options.herecomment;
if (herecomment) {
if (HEREDOC_ILLEGAL.test(doc)) {
- this.error("block comment cannot contain \"*/\", starting");
+ throw new Error("block comment cannot contain \"*/\", starting on line " + (this.line + 1));
}
- if (doc.indexOf('\n') < 0) {
+ if (doc.indexOf('\n') <= 0) {
return doc;
}
} else {
@@ -545,7 +448,6 @@ define(function(require, exports, module) {
}
return doc;
};
-
Lexer.prototype.tagParameters = function() {
var i, stack, tok, tokens;
if (this.tag() !== ')') {
@@ -567,43 +469,38 @@ define(function(require, exports, module) {
} else if (tok[0] === '(') {
tok[0] = 'PARAM_START';
return this;
- } else {
- return this;
}
}
}
return this;
};
-
Lexer.prototype.closeIndentation = function() {
return this.outdentToken(this.indent);
};
-
+ Lexer.prototype.identifierError = function(word) {
+ throw SyntaxError("Reserved word \"" + word + "\" on line " + (this.line + 1));
+ };
+ Lexer.prototype.assignmentError = function() {
+ throw SyntaxError("Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
+ };
Lexer.prototype.balancedString = function(str, end) {
- var continueCount, i, letter, match, prev, stack, _i, _ref2;
- continueCount = 0;
+ var i, letter, prev, stack, _ref2;
stack = [end];
- for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) {
- if (continueCount) {
- --continueCount;
- continue;
- }
+ for (i = 1, _ref2 = str.length; 1 <= _ref2 ? i < _ref2 : i > _ref2; 1 <= _ref2 ? i++ : i--) {
switch (letter = str.charAt(i)) {
case '\\':
- ++continueCount;
+ i++;
continue;
case end:
stack.pop();
if (!stack.length) {
- return str.slice(0, +i + 1 || 9e9);
+ return str.slice(0, i + 1);
}
end = stack[stack.length - 1];
continue;
}
if (end === '}' && (letter === '"' || letter === "'")) {
stack.push(end = letter);
- } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
- continueCount += match[0].length - 1;
} else if (end === '}' && letter === '{') {
stack.push(end = '}');
} else if (end === '"' && prev === '#' && letter === '{') {
@@ -611,18 +508,14 @@ define(function(require, exports, module) {
}
prev = letter;
}
- return this.error("missing " + (stack.pop()) + ", starting");
+ throw new Error("missing " + (stack.pop()) + ", starting on line " + (this.line + 1));
};
-
Lexer.prototype.interpolateString = function(str, options) {
- var column, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, rparen, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
+ var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _len, _ref2, _ref3, _ref4;
if (options == null) {
options = {};
}
- heredoc = options.heredoc, regex = options.regex, offsetInChunk = options.offsetInChunk, strOffset = options.strOffset, lexedLength = options.lexedLength;
- offsetInChunk = offsetInChunk || 0;
- strOffset = strOffset || 0;
- lexedLength = lexedLength || str.length;
+ heredoc = options.heredoc, regex = options.regex;
tokens = [];
pi = 0;
i = -1;
@@ -635,24 +528,22 @@ define(function(require, exports, module) {
continue;
}
if (pi < i) {
- tokens.push(this.makeToken('NEOSTRING', str.slice(pi, i), strOffset + pi));
+ tokens.push(['NEOSTRING', str.slice(pi, i)]);
}
inner = expr.slice(1, -1);
if (inner.length) {
- _ref2 = this.getLineAndColumnFromChunk(strOffset + i + 1), line = _ref2[0], column = _ref2[1];
nested = new Lexer().tokenize(inner, {
- line: line,
- column: column,
+ line: this.line,
rewrite: false
});
- popped = nested.pop();
- if (((_ref3 = nested[0]) != null ? _ref3[0] : void 0) === 'TERMINATOR') {
- popped = nested.shift();
+ nested.pop();
+ if (((_ref2 = nested[0]) != null ? _ref2[0] : void 0) === 'TERMINATOR') {
+ nested.shift();
}
if (len = nested.length) {
if (len > 1) {
- nested.unshift(this.makeToken('(', '(', strOffset + i + 1, 0));
- nested.push(this.makeToken(')', ')', strOffset + i + 1 + inner.length, 0));
+ nested.unshift(['(', '(']);
+ nested.push([')', ')']);
}
tokens.push(['TOKENS', nested]);
}
@@ -661,150 +552,60 @@ define(function(require, exports, module) {
pi = i + 1;
}
if ((i > pi && pi < str.length)) {
- tokens.push(this.makeToken('NEOSTRING', str.slice(pi), strOffset + pi));
+ tokens.push(['NEOSTRING', str.slice(pi)]);
}
if (regex) {
return tokens;
}
if (!tokens.length) {
- return this.token('STRING', '""', offsetInChunk, lexedLength);
+ return this.token('STRING', '""');
}
if (tokens[0][0] !== 'NEOSTRING') {
- tokens.unshift(this.makeToken('NEOSTRING', '', offsetInChunk));
+ tokens.unshift(['', '']);
}
if (interpolated = tokens.length > 1) {
- this.token('(', '(', offsetInChunk, 0);
+ this.token('(', '(');
}
- for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
- token = tokens[i];
- tag = token[0], value = token[1];
+ for (i = 0, _len = tokens.length; i < _len; i++) {
+ _ref3 = tokens[i], tag = _ref3[0], value = _ref3[1];
if (i) {
- if (i) {
- plusToken = this.token('+', '+');
- }
- locationToken = tag === 'TOKENS' ? value[0] : token;
- plusToken[2] = {
- first_line: locationToken[2].first_line,
- first_column: locationToken[2].first_column,
- last_line: locationToken[2].first_line,
- last_column: locationToken[2].first_column
- };
+ this.token('+', '+');
}
if (tag === 'TOKENS') {
(_ref4 = this.tokens).push.apply(_ref4, value);
- } else if (tag === 'NEOSTRING') {
- token[0] = 'STRING';
- token[1] = this.makeString(value, '"', heredoc);
- this.tokens.push(token);
} else {
- this.error("Unexpected " + tag);
+ this.token('STRING', this.makeString(value, '"', heredoc));
}
}
if (interpolated) {
- rparen = this.makeToken(')', ')', offsetInChunk + lexedLength, 0);
- rparen.stringEnd = true;
- this.tokens.push(rparen);
+ this.token(')', ')');
}
return tokens;
};
-
- Lexer.prototype.pair = function(tag) {
- var size, wanted;
- if (tag !== (wanted = last(this.ends))) {
- if ('OUTDENT' !== wanted) {
- this.error("unmatched " + tag);
- }
- this.indent -= size = last(this.indents);
- this.outdentToken(size, true);
- return this.pair(tag);
- }
- return this.ends.pop();
+ Lexer.prototype.token = function(tag, value) {
+ return this.tokens.push([tag, value, this.line]);
};
-
- Lexer.prototype.getLineAndColumnFromChunk = function(offset) {
- var column, lineCount, lines, string;
- if (offset === 0) {
- return [this.chunkLine, this.chunkColumn];
- }
- if (offset >= this.chunk.length) {
- string = this.chunk;
- } else {
- string = this.chunk.slice(0, +(offset - 1) + 1 || 9e9);
- }
- lineCount = count(string, '\n');
- column = this.chunkColumn;
- if (lineCount > 0) {
- lines = string.split('\n');
- column = last(lines).length;
- } else {
- column += string.length;
- }
- return [this.chunkLine + lineCount, column];
- };
-
- Lexer.prototype.makeToken = function(tag, value, offsetInChunk, length) {
- var lastCharacter, locationData, token, _ref2, _ref3;
- if (offsetInChunk == null) {
- offsetInChunk = 0;
- }
- if (length == null) {
- length = value.length;
- }
- locationData = {};
- _ref2 = this.getLineAndColumnFromChunk(offsetInChunk), locationData.first_line = _ref2[0], locationData.first_column = _ref2[1];
- lastCharacter = Math.max(0, length - 1);
- _ref3 = this.getLineAndColumnFromChunk(offsetInChunk + lastCharacter), locationData.last_line = _ref3[0], locationData.last_column = _ref3[1];
- token = [tag, value, locationData];
- return token;
- };
-
- Lexer.prototype.token = function(tag, value, offsetInChunk, length) {
- var token;
- token = this.makeToken(tag, value, offsetInChunk, length);
- this.tokens.push(token);
- return token;
- };
-
Lexer.prototype.tag = function(index, tag) {
var tok;
return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
};
-
Lexer.prototype.value = function(index, val) {
var tok;
return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
};
-
Lexer.prototype.unfinished = function() {
- var _ref2;
- return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
+ var prev, value;
+ return LINE_CONTINUER.test(this.chunk) || (prev = last(this.tokens, 1)) && prev[0] !== '.' && (value = this.value()) && !value.reserved && NO_NEWLINE.test(value) && !CODE.test(value) && !ASSIGNED.test(this.chunk);
};
-
- Lexer.prototype.removeNewlines = function(str) {
- return str.replace(/^\s*\n\s*/, '').replace(/([^\\]|\\\\)\s*\n\s*$/, '$1');
- };
-
Lexer.prototype.escapeLines = function(str, heredoc) {
- str = str.replace(/\\[^\S\n]*(\n|\\)\s*/g, function(escaped, character) {
- if (character === '\n') {
- return '';
- } else {
- return escaped;
- }
- });
- if (heredoc) {
- return str.replace(MULTILINER, '\\n');
- } else {
- return str.replace(/\s*\n\s*/g, ' ');
- }
+ return str.replace(MULTILINER, heredoc ? '\\n' : '');
};
-
Lexer.prototype.makeString = function(body, quote, heredoc) {
if (!body) {
return quote + quote;
}
- body = body.replace(RegExp("\\\\(" + quote + "|\\\\)", "g"), function(match, contents) {
- if (contents === quote) {
+ body = body.replace(/\\([\s\S])/g, function(match, contents) {
+ if (contents === '\n' || contents === quote) {
return contents;
} else {
return match;
@@ -813,27 +614,10 @@ define(function(require, exports, module) {
body = body.replace(RegExp("" + quote, "g"), '\\$&');
return quote + this.escapeLines(body, heredoc) + quote;
};
-
- Lexer.prototype.error = function(message, offset) {
- var first_column, first_line, _ref2;
- if (offset == null) {
- offset = 0;
- }
- _ref2 = this.getLineAndColumnFromChunk(offset), first_line = _ref2[0], first_column = _ref2[1];
- return throwSyntaxError(message, {
- first_line: first_line,
- first_column: first_column
- });
- };
-
return Lexer;
-
})();
-
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
-
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
-
COFFEE_ALIAS_MAP = {
and: '&&',
or: '||',
@@ -845,7 +629,6 @@ define(function(require, exports, module) {
on: 'true',
off: 'false'
};
-
COFFEE_ALIASES = (function() {
var _results;
_results = [];
@@ -854,82 +637,41 @@ define(function(require, exports, module) {
}
return _results;
})();
-
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES);
-
- RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static', 'yield'];
-
- STRICT_PROSCRIBED = ['arguments', 'eval'];
-
- JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED);
-
- exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED);
-
- exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED;
-
- BOM = 65279;
-
+ RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf'];
+ JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED);
+ exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS);
IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
-
- NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
-
- HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;
-
- OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?(\.|::)|\.{2,3})/;
-
+ NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i;
+ HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;
+ OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
WHITESPACE = /^[^\n\S]+/;
-
- COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/;
-
+ COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/;
CODE = /^[-=]>/;
-
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
-
- SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/;
-
+ SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
-
- REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
-
- HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;
-
- HEREGEX_OMIT = /((?:\\\\)+)|\\(\s|\/)|\s+(?:#.*)?/g;
-
+ REGEX = /^\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/[imgy]{0,4}(?!\w)/;
+ HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/;
+ HEREGEX_OMIT = /\s+(?:#.*)?/g;
MULTILINER = /\n/g;
-
HEREDOC_INDENT = /\n+([^\n\S]*)/g;
-
HEREDOC_ILLEGAL = /\*\//;
-
+ ASSIGNED = /^\s*@?([$A-Za-z_][$\w\x7f-\uffff]*|['"].*['"])[^\n\S]*?[:=][^:=>]/;
LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/;
-
TRAILING_SPACES = /\s+$/;
-
+ NO_NEWLINE = /^(?:[-+*&|\/%=<>!.\\][<>=&|]*|and|or|is(?:nt)?|n(?:ot|ew)|delete|typeof|instanceof)$/;
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
-
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO'];
-
LOGIC = ['&&', '||', '&', '|', '^'];
-
SHIFT = ['<<', '>>', '>>>'];
-
COMPARE = ['==', '!=', '<', '>', '<=', '>='];
-
MATH = ['*', '/', '%'];
-
RELATION = ['IN', 'OF', 'INSTANCEOF'];
-
- BOOL = ['TRUE', 'FALSE'];
-
- NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--'];
-
- NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']');
-
+ BOOL = ['TRUE', 'FALSE', 'NULL', 'UNDEFINED'];
+ NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']'];
+ NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
-
- INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL', 'NULL', 'UNDEFINED');
-
+ INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL');
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
-
-
-});
\ No newline at end of file
+});
diff --git a/ace/mode/coffee/nodes.js b/ace/mode/coffee/nodes.js
new file mode 100644
index 00000000..9e2702ea
--- /dev/null
+++ b/ace/mode/coffee/nodes.js
@@ -0,0 +1,2301 @@
+/**
+ * Copyright (c) 2011 Jeremy Ashkenas
+ *
+ * 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.
+ */
+
+define(function(require, exports, module) {
+ var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref;
+ var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
+ for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
+ function ctor() { this.constructor = child; }
+ ctor.prototype = parent.prototype;
+ child.prototype = new ctor;
+ child.__super__ = parent.prototype;
+ return child;
+ }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __indexOf = Array.prototype.indexOf || function(item) {
+ for (var i = 0, l = this.length; i < l; i++) {
+ if (this[i] === item) return i;
+ }
+ return -1;
+ };
+ Scope = require('ace/mode/coffee/scope').Scope;
+ _ref = require('ace/mode/coffee/helpers'), compact = _ref.compact, flatten = _ref.flatten, extend = _ref.extend, merge = _ref.merge, del = _ref.del, starts = _ref.starts, ends = _ref.ends, last = _ref.last;
+ exports.extend = extend;
+ YES = function() {
+ return true;
+ };
+ NO = function() {
+ return false;
+ };
+ THIS = function() {
+ return this;
+ };
+ NEGATE = function() {
+ this.negated = !this.negated;
+ return this;
+ };
+ exports.Base = Base = (function() {
+ function Base() {}
+ Base.prototype.compile = function(o, lvl) {
+ var node;
+ o = extend({}, o);
+ if (lvl) {
+ o.level = lvl;
+ }
+ node = this.unfoldSoak(o) || this;
+ node.tab = o.indent;
+ if (o.level === LEVEL_TOP || !node.isStatement(o)) {
+ return node.compileNode(o);
+ } else {
+ return node.compileClosure(o);
+ }
+ };
+ Base.prototype.compileClosure = function(o) {
+ if (this.jumps() || this instanceof Throw) {
+ throw SyntaxError('cannot use a pure statement in an expression.');
+ }
+ o.sharedScope = true;
+ return Closure.wrap(this).compileNode(o);
+ };
+ Base.prototype.cache = function(o, level, reused) {
+ var ref, sub;
+ if (!this.isComplex()) {
+ ref = level ? this.compile(o, level) : this;
+ return [ref, ref];
+ } else {
+ ref = new Literal(reused || o.scope.freeVariable('ref'));
+ sub = new Assign(ref, this);
+ if (level) {
+ return [sub.compile(o, level), ref.value];
+ } else {
+ return [sub, ref];
+ }
+ }
+ };
+ Base.prototype.compileLoopReference = function(o, name) {
+ var src, tmp;
+ src = tmp = this.compile(o, LEVEL_LIST);
+ if (!((-Infinity < +src && +src < Infinity) || IDENTIFIER.test(src) && o.scope.check(src, true))) {
+ src = "" + (tmp = o.scope.freeVariable(name)) + " = " + src;
+ }
+ return [src, tmp];
+ };
+ Base.prototype.makeReturn = function() {
+ return new Return(this);
+ };
+ Base.prototype.contains = function(pred) {
+ var contains;
+ contains = false;
+ this.traverseChildren(false, function(node) {
+ if (pred(node)) {
+ contains = true;
+ return false;
+ }
+ });
+ return contains;
+ };
+ Base.prototype.containsType = function(type) {
+ return this instanceof type || this.contains(function(node) {
+ return node instanceof type;
+ });
+ };
+ Base.prototype.lastNonComment = function(list) {
+ var i;
+ i = list.length;
+ while (i--) {
+ if (!(list[i] instanceof Comment)) {
+ return list[i];
+ }
+ }
+ return null;
+ };
+ Base.prototype.toString = function(idt, name) {
+ var tree;
+ if (idt == null) {
+ idt = '';
+ }
+ if (name == null) {
+ name = this.constructor.name;
+ }
+ tree = '\n' + idt + name;
+ if (this.soak) {
+ tree += '?';
+ }
+ this.eachChild(function(node) {
+ return tree += node.toString(idt + TAB);
+ });
+ return tree;
+ };
+ Base.prototype.eachChild = function(func) {
+ var attr, child, _i, _j, _len, _len2, _ref2, _ref3;
+ if (!this.children) {
+ return this;
+ }
+ _ref2 = this.children;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ attr = _ref2[_i];
+ if (this[attr]) {
+ _ref3 = flatten([this[attr]]);
+ for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
+ child = _ref3[_j];
+ if (func(child) === false) {
+ return this;
+ }
+ }
+ }
+ }
+ return this;
+ };
+ Base.prototype.traverseChildren = function(crossScope, func) {
+ return this.eachChild(function(child) {
+ if (func(child) === false) {
+ return false;
+ }
+ return child.traverseChildren(crossScope, func);
+ });
+ };
+ Base.prototype.invert = function() {
+ return new Op('!', this);
+ };
+ Base.prototype.unwrapAll = function() {
+ var node;
+ node = this;
+ while (node !== (node = node.unwrap())) {
+ continue;
+ }
+ return node;
+ };
+ Base.prototype.children = [];
+ Base.prototype.isStatement = NO;
+ Base.prototype.jumps = NO;
+ Base.prototype.isComplex = YES;
+ Base.prototype.isChainable = NO;
+ Base.prototype.isAssignable = NO;
+ Base.prototype.unwrap = THIS;
+ Base.prototype.unfoldSoak = NO;
+ Base.prototype.assigns = NO;
+ return Base;
+ })();
+ exports.Block = Block = (function() {
+ __extends(Block, Base);
+ function Block(nodes) {
+ this.expressions = compact(flatten(nodes || []));
+ }
+ Block.prototype.children = ['expressions'];
+ Block.prototype.push = function(node) {
+ this.expressions.push(node);
+ return this;
+ };
+ Block.prototype.pop = function() {
+ return this.expressions.pop();
+ };
+ Block.prototype.unshift = function(node) {
+ this.expressions.unshift(node);
+ return this;
+ };
+ Block.prototype.unwrap = function() {
+ if (this.expressions.length === 1) {
+ return this.expressions[0];
+ } else {
+ return this;
+ }
+ };
+ Block.prototype.isEmpty = function() {
+ return !this.expressions.length;
+ };
+ Block.prototype.isStatement = function(o) {
+ var exp, _i, _len, _ref2;
+ _ref2 = this.expressions;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ exp = _ref2[_i];
+ if (exp.isStatement(o)) {
+ return true;
+ }
+ }
+ return false;
+ };
+ Block.prototype.jumps = function(o) {
+ var exp, _i, _len, _ref2;
+ _ref2 = this.expressions;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ exp = _ref2[_i];
+ if (exp.jumps(o)) {
+ return exp;
+ }
+ }
+ };
+ Block.prototype.makeReturn = function() {
+ var expr, len;
+ len = this.expressions.length;
+ while (len--) {
+ expr = this.expressions[len];
+ if (!(expr instanceof Comment)) {
+ this.expressions[len] = expr.makeReturn();
+ if (expr instanceof Return && !expr.expression) {
+ this.expressions.splice(len, 1);
+ }
+ break;
+ }
+ }
+ return this;
+ };
+ Block.prototype.compile = function(o, level) {
+ if (o == null) {
+ o = {};
+ }
+ if (o.scope) {
+ return Block.__super__.compile.call(this, o, level);
+ } else {
+ return this.compileRoot(o);
+ }
+ };
+ Block.prototype.compileNode = function(o) {
+ var code, codes, node, top, _i, _len, _ref2;
+ this.tab = o.indent;
+ top = o.level === LEVEL_TOP;
+ codes = [];
+ _ref2 = this.expressions;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ node = _ref2[_i];
+ node = node.unwrapAll();
+ node = node.unfoldSoak(o) || node;
+ if (top) {
+ node.front = true;
+ code = node.compile(o);
+ codes.push(node.isStatement(o) ? code : this.tab + code + ';');
+ } else {
+ codes.push(node.compile(o, LEVEL_LIST));
+ }
+ }
+ if (top) {
+ return codes.join('\n');
+ }
+ code = codes.join(', ') || 'void 0';
+ if (codes.length > 1 && o.level >= LEVEL_LIST) {
+ return "(" + code + ")";
+ } else {
+ return code;
+ }
+ };
+ Block.prototype.compileRoot = function(o) {
+ var code;
+ o.indent = this.tab = o.bare ? '' : TAB;
+ o.scope = new Scope(null, this, null);
+ o.level = LEVEL_TOP;
+ code = this.compileWithDeclarations(o);
+ if (o.bare) {
+ return code;
+ } else {
+ return "(function() {\n" + code + "\n}).call(this);\n";
+ }
+ };
+ Block.prototype.compileWithDeclarations = function(o) {
+ var assigns, code, declars, exp, i, post, rest, scope, _len, _ref2;
+ code = post = '';
+ _ref2 = this.expressions;
+ for (i = 0, _len = _ref2.length; i < _len; i++) {
+ exp = _ref2[i];
+ exp = exp.unwrap();
+ if (!(exp instanceof Comment || exp instanceof Literal)) {
+ break;
+ }
+ }
+ o = merge(o, {
+ level: LEVEL_TOP
+ });
+ if (i) {
+ rest = this.expressions.splice(i, this.expressions.length);
+ code = this.compileNode(o);
+ this.expressions = rest;
+ }
+ post = this.compileNode(o);
+ scope = o.scope;
+ if (scope.expressions === this) {
+ declars = o.scope.hasDeclarations();
+ assigns = scope.hasAssignments;
+ if ((declars || assigns) && i) {
+ code += '\n';
+ }
+ if (declars) {
+ code += "" + this.tab + "var " + (scope.declaredVariables().join(', ')) + ";\n";
+ }
+ if (assigns) {
+ code += "" + this.tab + "var " + (multident(scope.assignedVariables().join(', '), this.tab)) + ";\n";
+ }
+ }
+ return code + post;
+ };
+ Block.wrap = function(nodes) {
+ if (nodes.length === 1 && nodes[0] instanceof Block) {
+ return nodes[0];
+ }
+ return new Block(nodes);
+ };
+ return Block;
+ })();
+ exports.Literal = Literal = (function() {
+ __extends(Literal, Base);
+ function Literal(value) {
+ this.value = value;
+ }
+ Literal.prototype.makeReturn = function() {
+ if (this.isStatement()) {
+ return this;
+ } else {
+ return new Return(this);
+ }
+ };
+ Literal.prototype.isAssignable = function() {
+ return IDENTIFIER.test(this.value);
+ };
+ Literal.prototype.isStatement = function() {
+ var _ref2;
+ return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger';
+ };
+ Literal.prototype.isComplex = NO;
+ Literal.prototype.assigns = function(name) {
+ return name === this.value;
+ };
+ Literal.prototype.jumps = function(o) {
+ if (!this.isStatement()) {
+ return false;
+ }
+ if (!(o && (o.loop || o.block && (this.value !== 'continue')))) {
+ return this;
+ } else {
+ return false;
+ }
+ };
+ Literal.prototype.compileNode = function(o) {
+ var code;
+ code = this.isUndefined ? o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0' : this.value.reserved ? "\"" + this.value + "\"" : this.value;
+ if (this.isStatement()) {
+ return "" + this.tab + code + ";";
+ } else {
+ return code;
+ }
+ };
+ Literal.prototype.toString = function() {
+ return ' "' + this.value + '"';
+ };
+ return Literal;
+ })();
+ exports.Return = Return = (function() {
+ __extends(Return, Base);
+ function Return(expr) {
+ if (expr && !expr.unwrap().isUndefined) {
+ this.expression = expr;
+ }
+ }
+ Return.prototype.children = ['expression'];
+ Return.prototype.isStatement = YES;
+ Return.prototype.makeReturn = THIS;
+ Return.prototype.jumps = THIS;
+ Return.prototype.compile = function(o, level) {
+ var expr, _ref2;
+ expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0;
+ if (expr && !(expr instanceof Return)) {
+ return expr.compile(o, level);
+ } else {
+ return Return.__super__.compile.call(this, o, level);
+ }
+ };
+ Return.prototype.compileNode = function(o) {
+ return this.tab + ("return" + (this.expression ? ' ' + this.expression.compile(o, LEVEL_PAREN) : '') + ";");
+ };
+ return Return;
+ })();
+ exports.Value = Value = (function() {
+ __extends(Value, Base);
+ function Value(base, props, tag) {
+ if (!props && base instanceof Value) {
+ return base;
+ }
+ this.base = base;
+ this.properties = props || [];
+ if (tag) {
+ this[tag] = true;
+ }
+ return this;
+ }
+ Value.prototype.children = ['base', 'properties'];
+ Value.prototype.push = function(prop) {
+ this.properties.push(prop);
+ return this;
+ };
+ Value.prototype.hasProperties = function() {
+ return !!this.properties.length;
+ };
+ Value.prototype.isArray = function() {
+ return !this.properties.length && this.base instanceof Arr;
+ };
+ Value.prototype.isComplex = function() {
+ return this.hasProperties() || this.base.isComplex();
+ };
+ Value.prototype.isAssignable = function() {
+ return this.hasProperties() || this.base.isAssignable();
+ };
+ Value.prototype.isSimpleNumber = function() {
+ return this.base instanceof Literal && SIMPLENUM.test(this.base.value);
+ };
+ Value.prototype.isAtomic = function() {
+ var node, _i, _len, _ref2;
+ _ref2 = this.properties.concat(this.base);
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ node = _ref2[_i];
+ if (node.soak || node instanceof Call) {
+ return false;
+ }
+ }
+ return true;
+ };
+ Value.prototype.isStatement = function(o) {
+ return !this.properties.length && this.base.isStatement(o);
+ };
+ Value.prototype.assigns = function(name) {
+ return !this.properties.length && this.base.assigns(name);
+ };
+ Value.prototype.jumps = function(o) {
+ return !this.properties.length && this.base.jumps(o);
+ };
+ Value.prototype.isObject = function(onlyGenerated) {
+ if (this.properties.length) {
+ return false;
+ }
+ return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
+ };
+ Value.prototype.isSplice = function() {
+ return last(this.properties) instanceof Slice;
+ };
+ Value.prototype.makeReturn = function() {
+ if (this.properties.length) {
+ return Value.__super__.makeReturn.call(this);
+ } else {
+ return this.base.makeReturn();
+ }
+ };
+ Value.prototype.unwrap = function() {
+ if (this.properties.length) {
+ return this;
+ } else {
+ return this.base;
+ }
+ };
+ Value.prototype.cacheReference = function(o) {
+ var base, bref, name, nref;
+ name = last(this.properties);
+ if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
+ return [this, this];
+ }
+ base = new Value(this.base, this.properties.slice(0, -1));
+ if (base.isComplex()) {
+ bref = new Literal(o.scope.freeVariable('base'));
+ base = new Value(new Parens(new Assign(bref, base)));
+ }
+ if (!name) {
+ return [base, bref];
+ }
+ if (name.isComplex()) {
+ nref = new Literal(o.scope.freeVariable('name'));
+ name = new Index(new Assign(nref, name.index));
+ nref = new Index(nref);
+ }
+ return [base.push(name), new Value(bref || base.base, [nref || name])];
+ };
+ Value.prototype.compileNode = function(o) {
+ var code, prop, props, _i, _len;
+ this.base.front = this.front;
+ props = this.properties;
+ code = this.base.compile(o, props.length ? LEVEL_ACCESS : null);
+ if (props[0] instanceof Access && this.isSimpleNumber()) {
+ code = "(" + code + ")";
+ }
+ for (_i = 0, _len = props.length; _i < _len; _i++) {
+ prop = props[_i];
+ code += prop.compile(o);
+ }
+ return code;
+ };
+ Value.prototype.unfoldSoak = function(o) {
+ var result;
+ if (this.unfoldedSoak != null) {
+ return this.unfoldedSoak;
+ }
+ result = __bind(function() {
+ var fst, i, ifn, prop, ref, snd, _len, _ref2;
+ if (ifn = this.base.unfoldSoak(o)) {
+ Array.prototype.push.apply(ifn.body.properties, this.properties);
+ return ifn;
+ }
+ _ref2 = this.properties;
+ for (i = 0, _len = _ref2.length; i < _len; i++) {
+ prop = _ref2[i];
+ if (prop.soak) {
+ prop.soak = false;
+ fst = new Value(this.base, this.properties.slice(0, i));
+ snd = new Value(this.base, this.properties.slice(i));
+ if (fst.isComplex()) {
+ ref = new Literal(o.scope.freeVariable('ref'));
+ fst = new Parens(new Assign(ref, fst));
+ snd.base = ref;
+ }
+ return new If(new Existence(fst), snd, {
+ soak: true
+ });
+ }
+ }
+ return null;
+ }, this)();
+ return this.unfoldedSoak = result || false;
+ };
+ return Value;
+ })();
+ exports.Comment = Comment = (function() {
+ __extends(Comment, Base);
+ function Comment(comment) {
+ this.comment = comment;
+ }
+ Comment.prototype.isStatement = YES;
+ Comment.prototype.makeReturn = THIS;
+ Comment.prototype.compileNode = function(o, level) {
+ var code;
+ code = '/*' + multident(this.comment, this.tab) + '*/';
+ if ((level || o.level) === LEVEL_TOP) {
+ code = o.indent + code;
+ }
+ return code;
+ };
+ return Comment;
+ })();
+ exports.Call = Call = (function() {
+ __extends(Call, Base);
+ function Call(variable, args, soak) {
+ this.args = args != null ? args : [];
+ this.soak = soak;
+ this.isNew = false;
+ this.isSuper = variable === 'super';
+ this.variable = this.isSuper ? null : variable;
+ }
+ Call.prototype.children = ['variable', 'args'];
+ Call.prototype.newInstance = function() {
+ var base;
+ base = this.variable.base || this.variable;
+ if (base instanceof Call) {
+ base.newInstance();
+ } else {
+ this.isNew = true;
+ }
+ return this;
+ };
+ Call.prototype.superReference = function(o) {
+ var method, name;
+ method = o.scope.method;
+ if (!method) {
+ throw SyntaxError('cannot call super outside of a function.');
+ }
+ name = method.name;
+ if (!name) {
+ throw SyntaxError('cannot call super on an anonymous function.');
+ }
+ if (method.klass) {
+ return "" + method.klass + ".__super__." + name;
+ } else {
+ return "" + name + ".__super__.constructor";
+ }
+ };
+ Call.prototype.unfoldSoak = function(o) {
+ var call, ifn, left, list, rite, _i, _len, _ref2, _ref3;
+ if (this.soak) {
+ if (this.variable) {
+ if (ifn = unfoldSoak(o, this, 'variable')) {
+ return ifn;
+ }
+ _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
+ } else {
+ left = new Literal(this.superReference(o));
+ rite = new Value(left);
+ }
+ rite = new Call(rite, this.args);
+ rite.isNew = this.isNew;
+ left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
+ return new If(left, new Value(rite), {
+ soak: true
+ });
+ }
+ call = this;
+ list = [];
+ while (true) {
+ if (call.variable instanceof Call) {
+ list.push(call);
+ call = call.variable;
+ continue;
+ }
+ if (!(call.variable instanceof Value)) {
+ break;
+ }
+ list.push(call);
+ if (!((call = call.variable.base) instanceof Call)) {
+ break;
+ }
+ }
+ _ref3 = list.reverse();
+ for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
+ call = _ref3[_i];
+ if (ifn) {
+ if (call.variable instanceof Call) {
+ call.variable = ifn;
+ } else {
+ call.variable.base = ifn;
+ }
+ }
+ ifn = unfoldSoak(o, call, 'variable');
+ }
+ return ifn;
+ };
+ Call.prototype.filterImplicitObjects = function(list) {
+ var node, nodes, obj, prop, properties, _i, _j, _len, _len2, _ref2;
+ nodes = [];
+ for (_i = 0, _len = list.length; _i < _len; _i++) {
+ node = list[_i];
+ if (!((typeof node.isObject === "function" ? node.isObject() : void 0) && node.base.generated)) {
+ nodes.push(node);
+ continue;
+ }
+ obj = null;
+ _ref2 = node.base.properties;
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
+ prop = _ref2[_j];
+ if (prop instanceof Assign) {
+ if (!obj) {
+ nodes.push(obj = new Obj(properties = [], true));
+ }
+ properties.push(prop);
+ } else {
+ nodes.push(prop);
+ obj = null;
+ }
+ }
+ }
+ return nodes;
+ };
+ Call.prototype.compileNode = function(o) {
+ var arg, args, code, _ref2;
+ if ((_ref2 = this.variable) != null) {
+ _ref2.front = this.front;
+ }
+ if (code = Splat.compileSplattedArray(o, this.args, true)) {
+ return this.compileSplat(o, code);
+ }
+ args = this.filterImplicitObjects(this.args);
+ args = ((function() {
+ var _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = args.length; _i < _len; _i++) {
+ arg = args[_i];
+ _results.push(arg.compile(o, LEVEL_LIST));
+ }
+ return _results;
+ })()).join(', ');
+ if (this.isSuper) {
+ return this.superReference(o) + (".call(this" + (args && ', ' + args) + ")");
+ } else {
+ return (this.isNew ? 'new ' : '') + this.variable.compile(o, LEVEL_ACCESS) + ("(" + args + ")");
+ }
+ };
+ Call.prototype.compileSuper = function(args, o) {
+ return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + args + ")";
+ };
+ Call.prototype.compileSplat = function(o, splatArgs) {
+ var base, fun, idt, name, ref;
+ if (this.isSuper) {
+ return "" + (this.superReference(o)) + ".apply(this, " + splatArgs + ")";
+ }
+ if (this.isNew) {
+ idt = this.tab + TAB;
+ return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return typeof result === \"object\" ? result : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function() {})";
+ }
+ base = new Value(this.variable);
+ if ((name = base.properties.pop()) && base.isComplex()) {
+ ref = o.scope.freeVariable('ref');
+ fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o));
+ } else {
+ fun = base.compile(o, LEVEL_ACCESS);
+ if (SIMPLENUM.test(fun)) {
+ fun = "(" + fun + ")";
+ }
+ if (name) {
+ ref = fun;
+ fun += name.compile(o);
+ } else {
+ ref = 'null';
+ }
+ }
+ return "" + fun + ".apply(" + ref + ", " + splatArgs + ")";
+ };
+ return Call;
+ })();
+ exports.Extends = Extends = (function() {
+ __extends(Extends, Base);
+ function Extends(child, parent) {
+ this.child = child;
+ this.parent = parent;
+ }
+ Extends.prototype.children = ['child', 'parent'];
+ Extends.prototype.compile = function(o) {
+ utility('hasProp');
+ return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o);
+ };
+ return Extends;
+ })();
+ exports.Access = Access = (function() {
+ __extends(Access, Base);
+ function Access(name, tag) {
+ this.name = name;
+ this.name.asKey = true;
+ this.proto = tag === 'proto' ? '.prototype' : '';
+ this.soak = tag === 'soak';
+ }
+ Access.prototype.children = ['name'];
+ Access.prototype.compile = function(o) {
+ var name;
+ name = this.name.compile(o);
+ return this.proto + (IS_STRING.test(name) ? "[" + name + "]" : "." + name);
+ };
+ Access.prototype.isComplex = NO;
+ return Access;
+ })();
+ exports.Index = Index = (function() {
+ __extends(Index, Base);
+ function Index(index) {
+ this.index = index;
+ }
+ Index.prototype.children = ['index'];
+ Index.prototype.compile = function(o) {
+ return (this.proto ? '.prototype' : '') + ("[" + (this.index.compile(o, LEVEL_PAREN)) + "]");
+ };
+ Index.prototype.isComplex = function() {
+ return this.index.isComplex();
+ };
+ return Index;
+ })();
+ exports.Range = Range = (function() {
+ __extends(Range, Base);
+ Range.prototype.children = ['from', 'to'];
+ function Range(from, to, tag) {
+ this.from = from;
+ this.to = to;
+ this.exclusive = tag === 'exclusive';
+ this.equals = this.exclusive ? '' : '=';
+ }
+ Range.prototype.compileVariables = function(o) {
+ var step, _ref2, _ref3, _ref4, _ref5;
+ o = merge(o, {
+ top: true
+ });
+ _ref2 = this.from.cache(o, LEVEL_LIST), this.from = _ref2[0], this.fromVar = _ref2[1];
+ _ref3 = this.to.cache(o, LEVEL_LIST), this.to = _ref3[0], this.toVar = _ref3[1];
+ if (step = del(o, 'step')) {
+ _ref4 = step.cache(o, LEVEL_LIST), this.step = _ref4[0], this.stepVar = _ref4[1];
+ }
+ _ref5 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref5[0], this.toNum = _ref5[1];
+ if (this.stepVar) {
+ return this.stepNum = this.stepVar.match(SIMPLENUM);
+ }
+ };
+ Range.prototype.compileNode = function(o) {
+ var cond, condPart, from, gt, idx, known, lt, stepPart, to, varPart, _ref2, _ref3;
+ if (!this.fromVar) {
+ this.compileVariables(o);
+ }
+ if (!o.index) {
+ return this.compileArray(o);
+ }
+ known = this.fromNum && this.toNum;
+ idx = del(o, 'index');
+ varPart = "" + idx + " = " + this.from;
+ if (this.to !== this.toVar) {
+ varPart += ", " + this.to;
+ }
+ if (this.step !== this.stepVar) {
+ varPart += ", " + this.step;
+ }
+ _ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
+ condPart = this.stepNum ? condPart = +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), condPart = from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = "" + this.fromVar + " <= " + this.toVar, condPart = "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
+ stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? from <= to ? "" + idx + "++" : "" + idx + "--" : "" + cond + " ? " + idx + "++ : " + idx + "--";
+ return "" + varPart + "; " + condPart + "; " + stepPart;
+ };
+ Range.prototype.compileArray = function(o) {
+ var body, cond, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results;
+ if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) {
+ range = (function() {
+ _results = [];
+ for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); }
+ return _results;
+ }).apply(this, arguments);
+ if (this.exclusive) {
+ range.pop();
+ }
+ return "[" + (range.join(', ')) + "]";
+ }
+ idt = this.tab + TAB;
+ i = o.scope.freeVariable('i');
+ result = o.scope.freeVariable('results');
+ pre = "\n" + idt + result + " = [];";
+ if (this.fromNum && this.toNum) {
+ o.index = i;
+ body = this.compileNode(o);
+ } else {
+ vars = ("" + i + " = " + this.from) + (this.to !== this.toVar ? ", " + this.to : '');
+ cond = "" + this.fromVar + " <= " + this.toVar;
+ body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--";
+ }
+ post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent;
+ return "(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this, arguments)";
+ };
+ return Range;
+ })();
+ exports.Slice = Slice = (function() {
+ __extends(Slice, Base);
+ Slice.prototype.children = ['range'];
+ function Slice(range) {
+ this.range = range;
+ Slice.__super__.constructor.call(this);
+ }
+ Slice.prototype.compileNode = function(o) {
+ var compiled, from, fromStr, to, toStr, _ref2;
+ _ref2 = this.range, to = _ref2.to, from = _ref2.from;
+ fromStr = from && from.compile(o, LEVEL_PAREN) || '0';
+ compiled = to && to.compile(o, LEVEL_PAREN);
+ if (to && !(!this.range.exclusive && +compiled === -1)) {
+ toStr = ', ' + (this.range.exclusive ? compiled : SIMPLENUM.test(compiled) ? (+compiled + 1).toString() : "(" + compiled + " + 1) || 9e9");
+ }
+ return ".slice(" + fromStr + (toStr || '') + ")";
+ };
+ return Slice;
+ })();
+ exports.Obj = Obj = (function() {
+ __extends(Obj, Base);
+ function Obj(props, generated) {
+ this.generated = generated != null ? generated : false;
+ this.objects = this.properties = props || [];
+ }
+ Obj.prototype.children = ['properties'];
+ Obj.prototype.compileNode = function(o) {
+ var i, idt, indent, join, lastNoncom, node, obj, prop, props, _i, _len;
+ props = this.properties;
+ if (!props.length) {
+ if (this.front) {
+ return '({})';
+ } else {
+ return '{}';
+ }
+ }
+ if (this.generated) {
+ for (_i = 0, _len = props.length; _i < _len; _i++) {
+ node = props[_i];
+ if (node instanceof Value) {
+ throw new Error('cannot have an implicit value in an implicit object');
+ }
+ }
+ }
+ idt = o.indent += TAB;
+ lastNoncom = this.lastNonComment(this.properties);
+ props = (function() {
+ var _len2, _results;
+ _results = [];
+ for (i = 0, _len2 = props.length; i < _len2; i++) {
+ prop = props[i];
+ join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
+ indent = prop instanceof Comment ? '' : idt;
+ if (prop instanceof Value && prop["this"]) {
+ prop = new Assign(prop.properties[0].name, prop, 'object');
+ }
+ if (!(prop instanceof Comment)) {
+ if (!(prop instanceof Assign)) {
+ prop = new Assign(prop, prop, 'object');
+ }
+ (prop.variable.base || prop.variable).asKey = true;
+ }
+ _results.push(indent + prop.compile(o, LEVEL_TOP) + join);
+ }
+ return _results;
+ })();
+ props = props.join('');
+ obj = "{" + (props && '\n' + props + '\n' + this.tab) + "}";
+ if (this.front) {
+ return "(" + obj + ")";
+ } else {
+ return obj;
+ }
+ };
+ Obj.prototype.assigns = function(name) {
+ var prop, _i, _len, _ref2;
+ _ref2 = this.properties;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ prop = _ref2[_i];
+ if (prop.assigns(name)) {
+ return true;
+ }
+ }
+ return false;
+ };
+ return Obj;
+ })();
+ exports.Arr = Arr = (function() {
+ __extends(Arr, Base);
+ function Arr(objs) {
+ this.objects = objs || [];
+ }
+ Arr.prototype.children = ['objects'];
+ Arr.prototype.filterImplicitObjects = Call.prototype.filterImplicitObjects;
+ Arr.prototype.compileNode = function(o) {
+ var code, obj, objs;
+ if (!this.objects.length) {
+ return '[]';
+ }
+ o.indent += TAB;
+ objs = this.filterImplicitObjects(this.objects);
+ if (code = Splat.compileSplattedArray(o, objs)) {
+ return code;
+ }
+ code = ((function() {
+ var _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = objs.length; _i < _len; _i++) {
+ obj = objs[_i];
+ _results.push(obj.compile(o, LEVEL_LIST));
+ }
+ return _results;
+ })()).join(', ');
+ if (code.indexOf('\n') >= 0) {
+ return "[\n" + o.indent + code + "\n" + this.tab + "]";
+ } else {
+ return "[" + code + "]";
+ }
+ };
+ Arr.prototype.assigns = function(name) {
+ var obj, _i, _len, _ref2;
+ _ref2 = this.objects;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ obj = _ref2[_i];
+ if (obj.assigns(name)) {
+ return true;
+ }
+ }
+ return false;
+ };
+ return Arr;
+ })();
+ exports.Class = Class = (function() {
+ __extends(Class, Base);
+ function Class(variable, parent, body) {
+ this.variable = variable;
+ this.parent = parent;
+ this.body = body != null ? body : new Block;
+ this.boundFuncs = [];
+ this.body.classBody = true;
+ }
+ Class.prototype.children = ['variable', 'parent', 'body'];
+ Class.prototype.determineName = function() {
+ var decl, tail;
+ if (!this.variable) {
+ return null;
+ }
+ decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value;
+ return decl && (decl = IDENTIFIER.test(decl) && decl);
+ };
+ Class.prototype.setContext = function(name) {
+ return this.body.traverseChildren(false, function(node) {
+ if (node.classBody) {
+ return false;
+ }
+ if (node instanceof Literal && node.value === 'this') {
+ return node.value = name;
+ } else if (node instanceof Code) {
+ node.klass = name;
+ if (node.bound) {
+ return node.context = name;
+ }
+ }
+ });
+ };
+ Class.prototype.addBoundFunctions = function(o) {
+ var bname, bvar, _i, _len, _ref2, _results;
+ if (this.boundFuncs.length) {
+ _ref2 = this.boundFuncs;
+ _results = [];
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ bvar = _ref2[_i];
+ bname = bvar.compile(o);
+ _results.push(this.ctor.body.unshift(new Literal("this." + bname + " = " + (utility('bind')) + "(this." + bname + ", this)")));
+ }
+ return _results;
+ }
+ };
+ Class.prototype.addProperties = function(node, name, o) {
+ var assign, base, exprs, func, props;
+ props = node.base.properties.slice(0);
+ exprs = (function() {
+ var _results;
+ _results = [];
+ while (assign = props.shift()) {
+ if (assign instanceof Assign) {
+ base = assign.variable.base;
+ delete assign.context;
+ func = assign.value;
+ if (base.value === 'constructor') {
+ if (this.ctor) {
+ throw new Error('cannot define more than one constructor in a class');
+ }
+ if (func.bound) {
+ throw new Error('cannot define a constructor as a bound function');
+ }
+ if (func instanceof Code) {
+ assign = this.ctor = func;
+ } else {
+ this.externalCtor = o.scope.freeVariable('class');
+ assign = new Assign(new Literal(this.externalCtor), func);
+ }
+ } else {
+ if (!assign.variable["this"]) {
+ assign.variable = new Value(new Literal(name), [new Access(base, 'proto')]);
+ }
+ if (func instanceof Code && func.bound) {
+ this.boundFuncs.push(base);
+ func.bound = false;
+ }
+ }
+ }
+ _results.push(assign);
+ }
+ return _results;
+ }).call(this);
+ return compact(exprs);
+ };
+ Class.prototype.walkBody = function(name, o) {
+ return this.traverseChildren(false, __bind(function(child) {
+ var exps, i, node, _len, _ref2;
+ if (child instanceof Class) {
+ return false;
+ }
+ if (child instanceof Block) {
+ _ref2 = exps = child.expressions;
+ for (i = 0, _len = _ref2.length; i < _len; i++) {
+ node = _ref2[i];
+ if (node instanceof Value && node.isObject(true)) {
+ exps[i] = this.addProperties(node, name, o);
+ }
+ }
+ return child.expressions = exps = flatten(exps);
+ }
+ }, this));
+ };
+ Class.prototype.ensureConstructor = function(name) {
+ if (!this.ctor) {
+ this.ctor = new Code;
+ if (this.parent) {
+ this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
+ }
+ if (this.externalCtor) {
+ this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
+ }
+ this.body.expressions.unshift(this.ctor);
+ }
+ this.ctor.ctor = this.ctor.name = name;
+ this.ctor.klass = null;
+ return this.ctor.noReturn = true;
+ };
+ Class.prototype.compileNode = function(o) {
+ var decl, klass, lname, name;
+ decl = this.determineName();
+ name = decl || this.name || '_Class';
+ lname = new Literal(name);
+ this.setContext(name);
+ this.walkBody(name, o);
+ this.ensureConstructor(name);
+ if (this.parent) {
+ this.body.expressions.unshift(new Extends(lname, this.parent));
+ }
+ if (!(this.ctor instanceof Code)) {
+ this.body.expressions.unshift(this.ctor);
+ }
+ this.body.expressions.push(lname);
+ this.addBoundFunctions(o);
+ klass = new Parens(Closure.wrap(this.body), true);
+ if (this.variable) {
+ klass = new Assign(this.variable, klass);
+ }
+ return klass.compile(o);
+ };
+ return Class;
+ })();
+ exports.Assign = Assign = (function() {
+ __extends(Assign, Base);
+ function Assign(variable, value, context, options) {
+ this.variable = variable;
+ this.value = value;
+ this.context = context;
+ this.param = options && options.param;
+ }
+ Assign.prototype.children = ['variable', 'value'];
+ Assign.prototype.assigns = function(name) {
+ return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
+ };
+ Assign.prototype.unfoldSoak = function(o) {
+ return unfoldSoak(o, this, 'variable');
+ };
+ Assign.prototype.compileNode = function(o) {
+ var isValue, match, name, val, _ref2;
+ if (isValue = this.variable instanceof Value) {
+ if (this.variable.isArray() || this.variable.isObject()) {
+ return this.compilePatternMatch(o);
+ }
+ if (this.variable.isSplice()) {
+ return this.compileSplice(o);
+ }
+ if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') {
+ return this.compileConditional(o);
+ }
+ }
+ name = this.variable.compile(o, LEVEL_LIST);
+ if (!(this.context || this.variable.isAssignable())) {
+ throw SyntaxError("\"" + (this.variable.compile(o)) + "\" cannot be assigned.");
+ }
+ if (!(this.context || isValue && (this.variable.namespaced || this.variable.hasProperties()))) {
+ if (this.param) {
+ o.scope.add(name, 'var');
+ } else {
+ o.scope.find(name);
+ }
+ }
+ if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) {
+ this.value.name = match[2];
+ if (match[1]) {
+ this.value.klass = match[1];
+ }
+ }
+ val = this.value.compile(o, LEVEL_LIST);
+ if (this.context === 'object') {
+ return "" + name + ": " + val;
+ }
+ val = name + (" " + (this.context || '=') + " ") + val;
+ if (o.level <= LEVEL_LIST) {
+ return val;
+ } else {
+ return "(" + val + ")";
+ }
+ };
+ Assign.prototype.compilePatternMatch = function(o) {
+ var acc, assigns, code, i, idx, isObject, ivar, obj, objects, olen, ref, rest, splat, top, val, value, vvar, _len, _ref2, _ref3, _ref4, _ref5;
+ top = o.level === LEVEL_TOP;
+ value = this.value;
+ objects = this.variable.base.objects;
+ if (!(olen = objects.length)) {
+ code = value.compile(o);
+ if (o.level >= LEVEL_OP) {
+ return "(" + code + ")";
+ } else {
+ return code;
+ }
+ }
+ isObject = this.variable.isObject();
+ if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) {
+ if (obj instanceof Assign) {
+ _ref2 = obj, idx = _ref2.variable.base, obj = _ref2.value;
+ } else {
+ if (obj.base instanceof Parens) {
+ _ref3 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref3[0], idx = _ref3[1];
+ } else {
+ idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
+ }
+ }
+ acc = IDENTIFIER.test(idx.unwrap().value || 0);
+ value = new Value(value);
+ value.properties.push(new (acc ? Access : Index)(idx));
+ return new Assign(obj, value, null, {
+ param: this.param
+ }).compile(o, LEVEL_TOP);
+ }
+ vvar = value.compile(o, LEVEL_LIST);
+ assigns = [];
+ splat = false;
+ if (!IDENTIFIER.test(vvar) || this.variable.assigns(vvar)) {
+ assigns.push("" + (ref = o.scope.freeVariable('ref')) + " = " + vvar);
+ vvar = ref;
+ }
+ for (i = 0, _len = objects.length; i < _len; i++) {
+ obj = objects[i];
+ idx = i;
+ if (isObject) {
+ if (obj instanceof Assign) {
+ _ref4 = obj, idx = _ref4.variable.base, obj = _ref4.value;
+ } else {
+ if (obj.base instanceof Parens) {
+ _ref5 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref5[0], idx = _ref5[1];
+ } else {
+ idx = obj["this"] ? obj.properties[0].name : obj;
+ }
+ }
+ }
+ if (!splat && obj instanceof Splat) {
+ val = "" + olen + " <= " + vvar + ".length ? " + (utility('slice')) + ".call(" + vvar + ", " + i;
+ if (rest = olen - i - 1) {
+ ivar = o.scope.freeVariable('i');
+ val += ", " + ivar + " = " + vvar + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])";
+ } else {
+ val += ") : []";
+ }
+ val = new Literal(val);
+ splat = "" + ivar + "++";
+ } else {
+ if (obj instanceof Splat) {
+ obj = obj.name.compile(o);
+ throw SyntaxError("multiple splats are disallowed in an assignment: " + obj + " ...");
+ }
+ if (typeof idx === 'number') {
+ idx = new Literal(splat || idx);
+ acc = false;
+ } else {
+ acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
+ }
+ val = new Value(new Literal(vvar), [new (acc ? Access : Index)(idx)]);
+ }
+ assigns.push(new Assign(obj, val, null, {
+ param: this.param
+ }).compile(o, LEVEL_TOP));
+ }
+ if (!top) {
+ assigns.push(vvar);
+ }
+ code = assigns.join(', ');
+ if (o.level < LEVEL_LIST) {
+ return code;
+ } else {
+ return "(" + code + ")";
+ }
+ };
+ Assign.prototype.compileConditional = function(o) {
+ var left, rite, _ref2;
+ _ref2 = this.variable.cacheReference(o), left = _ref2[0], rite = _ref2[1];
+ if (__indexOf.call(this.context, "?") >= 0) {
+ o.isExistentialEquals = true;
+ }
+ return new Op(this.context.slice(0, -1), left, new Assign(rite, this.value, '=')).compile(o);
+ };
+ Assign.prototype.compileSplice = function(o) {
+ var code, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4;
+ _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive;
+ name = this.variable.compile(o);
+ _ref3 = (from != null ? from.cache(o, LEVEL_OP) : void 0) || ['0', '0'], fromDecl = _ref3[0], fromRef = _ref3[1];
+ if (to) {
+ if ((from != null ? from.isSimpleNumber() : void 0) && to.isSimpleNumber()) {
+ to = +to.compile(o) - +fromRef;
+ if (!exclusive) {
+ to += 1;
+ }
+ } else {
+ to = to.compile(o) + ' - ' + fromRef;
+ if (!exclusive) {
+ to += ' + 1';
+ }
+ }
+ } else {
+ to = "9e9";
+ }
+ _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1];
+ code = "[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat(" + valDef + ")), " + valRef;
+ if (o.level > LEVEL_TOP) {
+ return "(" + code + ")";
+ } else {
+ return code;
+ }
+ };
+ return Assign;
+ })();
+ exports.Code = Code = (function() {
+ __extends(Code, Base);
+ function Code(params, body, tag) {
+ this.params = params || [];
+ this.body = body || new Block;
+ this.bound = tag === 'boundfunc';
+ if (this.bound) {
+ this.context = 'this';
+ }
+ }
+ Code.prototype.children = ['params', 'body'];
+ Code.prototype.isStatement = function() {
+ return !!this.ctor;
+ };
+ Code.prototype.jumps = NO;
+ Code.prototype.compileNode = function(o) {
+ var code, exprs, i, idt, lit, p, param, ref, splats, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref2, _ref3, _ref4, _ref5;
+ o.scope = new Scope(o.scope, this.body, this);
+ o.scope.shared = del(o, 'sharedScope');
+ o.indent += TAB;
+ delete o.bare;
+ vars = [];
+ exprs = [];
+ _ref2 = this.params;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ param = _ref2[_i];
+ if (param.splat) {
+ _ref3 = this.params;
+ for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
+ p = _ref3[_j];
+ if (p.name.value) {
+ o.scope.add(p.name.value, 'var', true);
+ }
+ }
+ splats = new Assign(new Value(new Arr((function() {
+ var _k, _len3, _ref4, _results;
+ _ref4 = this.params;
+ _results = [];
+ for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) {
+ p = _ref4[_k];
+ _results.push(p.asReference(o));
+ }
+ return _results;
+ }).call(this))), new Value(new Literal('arguments')));
+ break;
+ }
+ }
+ _ref4 = this.params;
+ for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) {
+ param = _ref4[_k];
+ if (param.isComplex()) {
+ val = ref = param.asReference(o);
+ if (param.value) {
+ val = new Op('?', ref, param.value);
+ }
+ exprs.push(new Assign(new Value(param.name), val, '=', {
+ param: true
+ }));
+ } else {
+ ref = param;
+ if (param.value) {
+ lit = new Literal(ref.name.value + ' == null');
+ val = new Assign(new Value(param.name), param.value, '=');
+ exprs.push(new If(lit, val));
+ }
+ }
+ if (!splats) {
+ vars.push(ref);
+ }
+ }
+ wasEmpty = this.body.isEmpty();
+ if (splats) {
+ exprs.unshift(splats);
+ }
+ if (exprs.length) {
+ (_ref5 = this.body.expressions).unshift.apply(_ref5, exprs);
+ }
+ if (!splats) {
+ for (i = 0, _len4 = vars.length; i < _len4; i++) {
+ v = vars[i];
+ o.scope.parameter(vars[i] = v.compile(o));
+ }
+ }
+ if (!(wasEmpty || this.noReturn)) {
+ this.body.makeReturn();
+ }
+ idt = o.indent;
+ code = 'function';
+ if (this.ctor) {
+ code += ' ' + this.name;
+ }
+ code += '(' + vars.join(', ') + ') {';
+ if (!this.body.isEmpty()) {
+ code += "\n" + (this.body.compileWithDeclarations(o)) + "\n" + this.tab;
+ }
+ code += '}';
+ if (this.ctor) {
+ return this.tab + code;
+ }
+ if (this.bound) {
+ return utility('bind') + ("(" + code + ", " + this.context + ")");
+ }
+ if (this.front || (o.level >= LEVEL_ACCESS)) {
+ return "(" + code + ")";
+ } else {
+ return code;
+ }
+ };
+ Code.prototype.traverseChildren = function(crossScope, func) {
+ if (crossScope) {
+ return Code.__super__.traverseChildren.call(this, crossScope, func);
+ }
+ };
+ return Code;
+ })();
+ exports.Param = Param = (function() {
+ __extends(Param, Base);
+ function Param(name, value, splat) {
+ this.name = name;
+ this.value = value;
+ this.splat = splat;
+ }
+ Param.prototype.children = ['name', 'value'];
+ Param.prototype.compile = function(o) {
+ return this.name.compile(o, LEVEL_LIST);
+ };
+ Param.prototype.asReference = function(o) {
+ var node;
+ if (this.reference) {
+ return this.reference;
+ }
+ node = this.name;
+ if (node["this"]) {
+ node = node.properties[0].name;
+ if (node.value.reserved) {
+ node = new Literal('_' + node.value);
+ }
+ } else if (node.isComplex()) {
+ node = new Literal(o.scope.freeVariable('arg'));
+ }
+ node = new Value(node);
+ if (this.splat) {
+ node = new Splat(node);
+ }
+ return this.reference = node;
+ };
+ Param.prototype.isComplex = function() {
+ return this.name.isComplex();
+ };
+ return Param;
+ })();
+ exports.Splat = Splat = (function() {
+ __extends(Splat, Base);
+ Splat.prototype.children = ['name'];
+ Splat.prototype.isAssignable = YES;
+ function Splat(name) {
+ this.name = name.compile ? name : new Literal(name);
+ }
+ Splat.prototype.assigns = function(name) {
+ return this.name.assigns(name);
+ };
+ Splat.prototype.compile = function(o) {
+ if (this.index != null) {
+ return this.compileParam(o);
+ } else {
+ return this.name.compile(o);
+ }
+ };
+ Splat.compileSplattedArray = function(o, list, apply) {
+ var args, base, code, i, index, node, _len;
+ index = -1;
+ while ((node = list[++index]) && !(node instanceof Splat)) {
+ continue;
+ }
+ if (index >= list.length) {
+ return '';
+ }
+ if (list.length === 1) {
+ code = list[0].compile(o, LEVEL_LIST);
+ if (apply) {
+ return code;
+ }
+ return "" + (utility('slice')) + ".call(" + code + ")";
+ }
+ args = list.slice(index);
+ for (i = 0, _len = args.length; i < _len; i++) {
+ node = args[i];
+ code = node.compile(o, LEVEL_LIST);
+ args[i] = node instanceof Splat ? "" + (utility('slice')) + ".call(" + code + ")" : "[" + code + "]";
+ }
+ if (index === 0) {
+ return args[0] + (".concat(" + (args.slice(1).join(', ')) + ")");
+ }
+ base = (function() {
+ var _i, _len2, _ref2, _results;
+ _ref2 = list.slice(0, index);
+ _results = [];
+ for (_i = 0, _len2 = _ref2.length; _i < _len2; _i++) {
+ node = _ref2[_i];
+ _results.push(node.compile(o, LEVEL_LIST));
+ }
+ return _results;
+ })();
+ return "[" + (base.join(', ')) + "].concat(" + (args.join(', ')) + ")";
+ };
+ return Splat;
+ })();
+ exports.While = While = (function() {
+ __extends(While, Base);
+ function While(condition, options) {
+ this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition;
+ this.guard = options != null ? options.guard : void 0;
+ }
+ While.prototype.children = ['condition', 'guard', 'body'];
+ While.prototype.isStatement = YES;
+ While.prototype.makeReturn = function() {
+ this.returns = true;
+ return this;
+ };
+ While.prototype.addBody = function(body) {
+ this.body = body;
+ return this;
+ };
+ While.prototype.jumps = function() {
+ var expressions, node, _i, _len;
+ expressions = this.body.expressions;
+ if (!expressions.length) {
+ return false;
+ }
+ for (_i = 0, _len = expressions.length; _i < _len; _i++) {
+ node = expressions[_i];
+ if (node.jumps({
+ loop: true
+ })) {
+ return node;
+ }
+ }
+ return false;
+ };
+ While.prototype.compileNode = function(o) {
+ var body, code, rvar, set;
+ o.indent += TAB;
+ set = '';
+ body = this.body;
+ if (body.isEmpty()) {
+ body = '';
+ } else {
+ if (o.level > LEVEL_TOP || this.returns) {
+ rvar = o.scope.freeVariable('results');
+ set = "" + this.tab + rvar + " = [];\n";
+ if (body) {
+ body = Push.wrap(rvar, body);
+ }
+ }
+ if (this.guard) {
+ body = Block.wrap([new If(this.guard, body)]);
+ }
+ body = "\n" + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab;
+ }
+ code = set + this.tab + ("while (" + (this.condition.compile(o, LEVEL_PAREN)) + ") {" + body + "}");
+ if (this.returns) {
+ code += "\n" + this.tab + "return " + rvar + ";";
+ }
+ return code;
+ };
+ return While;
+ })();
+ exports.Op = Op = (function() {
+ var CONVERSIONS, INVERSIONS;
+ __extends(Op, Base);
+ function Op(op, first, second, flip) {
+ var call;
+ if (op === 'in') {
+ return new In(first, second);
+ }
+ if (op === 'do') {
+ call = new Call(first, first.params || []);
+ call["do"] = true;
+ return call;
+ }
+ if (op === 'new') {
+ if (first instanceof Call && !first["do"]) {
+ return first.newInstance();
+ }
+ if (first instanceof Code && first.bound || first["do"]) {
+ first = new Parens(first);
+ }
+ }
+ this.operator = CONVERSIONS[op] || op;
+ this.first = first;
+ this.second = second;
+ this.flip = !!flip;
+ return this;
+ }
+ CONVERSIONS = {
+ '==': '===',
+ '!=': '!==',
+ 'of': 'in'
+ };
+ INVERSIONS = {
+ '!==': '===',
+ '===': '!=='
+ };
+ Op.prototype.children = ['first', 'second'];
+ Op.prototype.isSimpleNumber = NO;
+ Op.prototype.isUnary = function() {
+ return !this.second;
+ };
+ Op.prototype.isComplex = function() {
+ var _ref2;
+ return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex();
+ };
+ Op.prototype.isChainable = function() {
+ var _ref2;
+ return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!==';
+ };
+ Op.prototype.invert = function() {
+ var allInvertable, curr, fst, op, _ref2;
+ if (this.isChainable() && this.first.isChainable()) {
+ allInvertable = true;
+ curr = this;
+ while (curr && curr.operator) {
+ allInvertable && (allInvertable = curr.operator in INVERSIONS);
+ curr = curr.first;
+ }
+ if (!allInvertable) {
+ return new Parens(this).invert();
+ }
+ curr = this;
+ while (curr && curr.operator) {
+ curr.invert = !curr.invert;
+ curr.operator = INVERSIONS[curr.operator];
+ curr = curr.first;
+ }
+ return this;
+ } else if (op = INVERSIONS[this.operator]) {
+ this.operator = op;
+ if (this.first.unwrap() instanceof Op) {
+ this.first.invert();
+ }
+ return this;
+ } else if (this.second) {
+ return new Parens(this).invert();
+ } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
+ return fst;
+ } else {
+ return new Op('!', this);
+ }
+ };
+ Op.prototype.unfoldSoak = function(o) {
+ var _ref2;
+ return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
+ };
+ Op.prototype.compileNode = function(o) {
+ var code;
+ if (this.isUnary()) {
+ return this.compileUnary(o);
+ }
+ if (this.isChainable() && this.first.isChainable()) {
+ return this.compileChain(o);
+ }
+ if (this.operator === '?') {
+ return this.compileExistence(o);
+ }
+ this.first.front = this.front;
+ code = this.first.compile(o, LEVEL_OP) + ' ' + this.operator + ' ' + this.second.compile(o, LEVEL_OP);
+ if (o.level <= LEVEL_OP) {
+ return code;
+ } else {
+ return "(" + code + ")";
+ }
+ };
+ Op.prototype.compileChain = function(o) {
+ var code, fst, shared, _ref2;
+ _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1];
+ fst = this.first.compile(o, LEVEL_OP);
+ code = "" + fst + " " + (this.invert ? '&&' : '||') + " " + (shared.compile(o)) + " " + this.operator + " " + (this.second.compile(o, LEVEL_OP));
+ return "(" + code + ")";
+ };
+ Op.prototype.compileExistence = function(o) {
+ var fst, ref;
+ if (this.first.isComplex()) {
+ ref = new Literal(o.scope.freeVariable('ref'));
+ fst = new Parens(new Assign(ref, this.first));
+ } else {
+ fst = this.first;
+ ref = fst;
+ }
+ return new If(new Existence(fst), ref, {
+ type: 'if'
+ }).addElse(this.second).compile(o);
+ };
+ Op.prototype.compileUnary = function(o) {
+ var op, parts;
+ parts = [op = this.operator];
+ if ((op === 'new' || op === 'typeof' || op === 'delete') || (op === '+' || op === '-') && this.first instanceof Op && this.first.operator === op) {
+ parts.push(' ');
+ }
+ if (op === 'new' && this.first.isStatement(o)) {
+ this.first = new Parens(this.first);
+ }
+ parts.push(this.first.compile(o, LEVEL_OP));
+ if (this.flip) {
+ parts.reverse();
+ }
+ return parts.join('');
+ };
+ Op.prototype.toString = function(idt) {
+ return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
+ };
+ return Op;
+ })();
+ exports.In = In = (function() {
+ __extends(In, Base);
+ function In(object, array) {
+ this.object = object;
+ this.array = array;
+ }
+ In.prototype.children = ['object', 'array'];
+ In.prototype.invert = NEGATE;
+ In.prototype.compileNode = function(o) {
+ var hasSplat, obj, _i, _len, _ref2;
+ if (this.array instanceof Value && this.array.isArray()) {
+ _ref2 = this.array.base.objects;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ obj = _ref2[_i];
+ if (obj instanceof Splat) {
+ hasSplat = true;
+ break;
+ }
+ }
+ if (!hasSplat) {
+ return this.compileOrTest(o);
+ }
+ }
+ return this.compileLoopTest(o);
+ };
+ In.prototype.compileOrTest = function(o) {
+ var cmp, cnj, i, item, ref, sub, tests, _ref2, _ref3;
+ _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1];
+ _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1];
+ tests = (function() {
+ var _len, _ref4, _results;
+ _ref4 = this.array.base.objects;
+ _results = [];
+ for (i = 0, _len = _ref4.length; i < _len; i++) {
+ item = _ref4[i];
+ _results.push((i ? ref : sub) + cmp + item.compile(o, LEVEL_OP));
+ }
+ return _results;
+ }).call(this);
+ if (tests.length === 0) {
+ return 'false';
+ }
+ tests = tests.join(cnj);
+ if (o.level < LEVEL_OP) {
+ return tests;
+ } else {
+ return "(" + tests + ")";
+ }
+ };
+ In.prototype.compileLoopTest = function(o) {
+ var code, ref, sub, _ref2;
+ _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1];
+ code = utility('indexOf') + (".call(" + (this.array.compile(o, LEVEL_LIST)) + ", " + ref + ") ") + (this.negated ? '< 0' : '>= 0');
+ if (sub === ref) {
+ return code;
+ }
+ code = sub + ', ' + code;
+ if (o.level < LEVEL_LIST) {
+ return code;
+ } else {
+ return "(" + code + ")";
+ }
+ };
+ In.prototype.toString = function(idt) {
+ return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : ''));
+ };
+ return In;
+ })();
+ exports.Try = Try = (function() {
+ __extends(Try, Base);
+ function Try(attempt, error, recovery, ensure) {
+ this.attempt = attempt;
+ this.error = error;
+ this.recovery = recovery;
+ this.ensure = ensure;
+ }
+ Try.prototype.children = ['attempt', 'recovery', 'ensure'];
+ Try.prototype.isStatement = YES;
+ Try.prototype.jumps = function(o) {
+ var _ref2;
+ return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0);
+ };
+ Try.prototype.makeReturn = function() {
+ if (this.attempt) {
+ this.attempt = this.attempt.makeReturn();
+ }
+ if (this.recovery) {
+ this.recovery = this.recovery.makeReturn();
+ }
+ return this;
+ };
+ Try.prototype.compileNode = function(o) {
+ var catchPart, errorPart;
+ o.indent += TAB;
+ errorPart = this.error ? " (" + (this.error.compile(o)) + ") " : ' ';
+ catchPart = this.recovery ? " catch" + errorPart + "{\n" + (this.recovery.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}" : !(this.ensure || this.recovery) ? ' catch (_e) {}' : void 0;
+ return ("" + this.tab + "try {\n" + (this.attempt.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}" + (catchPart || '')) + (this.ensure ? " finally {\n" + (this.ensure.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}" : '');
+ };
+ return Try;
+ })();
+ exports.Throw = Throw = (function() {
+ __extends(Throw, Base);
+ function Throw(expression) {
+ this.expression = expression;
+ }
+ Throw.prototype.children = ['expression'];
+ Throw.prototype.isStatement = YES;
+ Throw.prototype.jumps = NO;
+ Throw.prototype.makeReturn = THIS;
+ Throw.prototype.compileNode = function(o) {
+ return this.tab + ("throw " + (this.expression.compile(o)) + ";");
+ };
+ return Throw;
+ })();
+ exports.Existence = Existence = (function() {
+ __extends(Existence, Base);
+ function Existence(expression) {
+ this.expression = expression;
+ }
+ Existence.prototype.children = ['expression'];
+ Existence.prototype.invert = NEGATE;
+ Existence.prototype.compileNode = function(o) {
+ var cmp, cnj, code, _ref2;
+ code = this.expression.compile(o, LEVEL_OP);
+ code = IDENTIFIER.test(code) && !o.scope.check(code) ? ((_ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1], _ref2), "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null") : "" + code + " " + (this.negated ? '==' : '!=') + " null";
+ if (o.level <= LEVEL_COND) {
+ return code;
+ } else {
+ return "(" + code + ")";
+ }
+ };
+ return Existence;
+ })();
+ exports.Parens = Parens = (function() {
+ __extends(Parens, Base);
+ function Parens(body) {
+ this.body = body;
+ }
+ Parens.prototype.children = ['body'];
+ Parens.prototype.unwrap = function() {
+ return this.body;
+ };
+ Parens.prototype.isComplex = function() {
+ return this.body.isComplex();
+ };
+ Parens.prototype.makeReturn = function() {
+ return this.body.makeReturn();
+ };
+ Parens.prototype.compileNode = function(o) {
+ var bare, code, expr;
+ expr = this.body.unwrap();
+ if (expr instanceof Value && expr.isAtomic()) {
+ expr.front = this.front;
+ return expr.compile(o);
+ }
+ code = expr.compile(o, LEVEL_PAREN);
+ bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns));
+ if (bare) {
+ return code;
+ } else {
+ return "(" + code + ")";
+ }
+ };
+ return Parens;
+ })();
+ exports.For = For = (function() {
+ __extends(For, Base);
+ function For(body, source) {
+ var _ref2;
+ this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
+ this.body = Block.wrap([body]);
+ this.own = !!source.own;
+ this.object = !!source.object;
+ if (this.object) {
+ _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1];
+ }
+ if (this.index instanceof Value) {
+ throw SyntaxError('index cannot be a pattern matching expression');
+ }
+ this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length;
+ this.pattern = this.name instanceof Value;
+ if (this.range && this.index) {
+ throw SyntaxError('indexes do not apply to range loops');
+ }
+ if (this.range && this.pattern) {
+ throw SyntaxError('cannot pattern match over range loops');
+ }
+ this.returns = false;
+ }
+ For.prototype.children = ['body', 'source', 'guard', 'step'];
+ For.prototype.isStatement = YES;
+ For.prototype.jumps = While.prototype.jumps;
+ For.prototype.makeReturn = function() {
+ this.returns = true;
+ return this;
+ };
+ For.prototype.compileNode = function(o) {
+ var body, defPart, forPart, forVarPart, guardPart, idt1, index, ivar, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, stepvar, svar, varPart, _ref2;
+ body = Block.wrap([this.body]);
+ lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
+ if (lastJumps && lastJumps instanceof Return) {
+ this.returns = false;
+ }
+ source = this.range ? this.source.base : this.source;
+ scope = o.scope;
+ name = this.name && this.name.compile(o, LEVEL_LIST);
+ index = this.index && this.index.compile(o, LEVEL_LIST);
+ if (name && !this.pattern) {
+ scope.find(name, {
+ immediate: true
+ });
+ }
+ if (index) {
+ scope.find(index, {
+ immediate: true
+ });
+ }
+ if (this.returns) {
+ rvar = scope.freeVariable('results');
+ }
+ ivar = (this.range ? name : index) || scope.freeVariable('i');
+ if (this.step && !this.range) {
+ stepvar = scope.freeVariable("step");
+ }
+ if (this.pattern) {
+ name = ivar;
+ }
+ varPart = '';
+ guardPart = '';
+ defPart = '';
+ idt1 = this.tab + TAB;
+ if (this.range) {
+ forPart = source.compile(merge(o, {
+ index: ivar,
+ step: this.step
+ }));
+ } else {
+ svar = this.source.compile(o, LEVEL_LIST);
+ if ((name || this.own) && !IDENTIFIER.test(svar)) {
+ defPart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n";
+ svar = ref;
+ }
+ if (name && !this.pattern) {
+ namePart = "" + name + " = " + svar + "[" + ivar + "]";
+ }
+ if (!this.object) {
+ lvar = scope.freeVariable('len');
+ forVarPart = ("" + ivar + " = 0, " + lvar + " = " + svar + ".length") + (this.step ? ", " + stepvar + " = " + (this.step.compile(o, LEVEL_OP)) : '');
+ stepPart = this.step ? "" + ivar + " += " + stepvar : "" + ivar + "++";
+ forPart = "" + forVarPart + "; " + ivar + " < " + lvar + "; " + stepPart;
+ }
+ }
+ if (this.returns) {
+ resultPart = "" + this.tab + rvar + " = [];\n";
+ returnResult = "\n" + this.tab + "return " + rvar + ";";
+ body = Push.wrap(rvar, body);
+ }
+ if (this.guard) {
+ body = Block.wrap([new If(this.guard, body)]);
+ }
+ if (this.pattern) {
+ body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + ivar + "]")));
+ }
+ defPart += this.pluckDirectCall(o, body);
+ if (namePart) {
+ varPart = "\n" + idt1 + namePart + ";";
+ }
+ if (this.object) {
+ forPart = "" + ivar + " in " + svar;
+ if (this.own) {
+ guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")) continue;";
+ }
+ }
+ body = body.compile(merge(o, {
+ indent: idt1
+ }), LEVEL_TOP);
+ if (body) {
+ body = '\n' + body + '\n';
+ }
+ return "" + defPart + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + varPart + body + this.tab + "}" + (returnResult || '');
+ };
+ For.prototype.pluckDirectCall = function(o, body) {
+ var base, defs, expr, fn, idx, ref, val, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
+ defs = '';
+ _ref2 = body.expressions;
+ for (idx = 0, _len = _ref2.length; idx < _len; idx++) {
+ expr = _ref2[idx];
+ expr = expr.unwrapAll();
+ if (!(expr instanceof Call)) {
+ continue;
+ }
+ val = expr.variable.unwrapAll();
+ if (!((val instanceof Code) || (val instanceof Value && ((_ref3 = val.base) != null ? _ref3.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref4 = (_ref5 = val.properties[0].name) != null ? _ref5.value : void 0) === 'call' || _ref4 === 'apply')))) {
+ continue;
+ }
+ fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val;
+ ref = new Literal(o.scope.freeVariable('fn'));
+ base = new Value(ref);
+ if (val.base) {
+ _ref7 = [base, val], val.base = _ref7[0], base = _ref7[1];
+ args.unshift(new Literal('this'));
+ }
+ body.expressions[idx] = new Call(base, expr.args);
+ defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n';
+ }
+ return defs;
+ };
+ return For;
+ })();
+ exports.Switch = Switch = (function() {
+ __extends(Switch, Base);
+ function Switch(subject, cases, otherwise) {
+ this.subject = subject;
+ this.cases = cases;
+ this.otherwise = otherwise;
+ }
+ Switch.prototype.children = ['subject', 'cases', 'otherwise'];
+ Switch.prototype.isStatement = YES;
+ Switch.prototype.jumps = function(o) {
+ var block, conds, _i, _len, _ref2, _ref3, _ref4;
+ if (o == null) {
+ o = {
+ block: true
+ };
+ }
+ _ref2 = this.cases;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1];
+ if (block.jumps(o)) {
+ return block;
+ }
+ }
+ return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0;
+ };
+ Switch.prototype.makeReturn = function() {
+ var pair, _i, _len, _ref2, _ref3;
+ _ref2 = this.cases;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ pair = _ref2[_i];
+ pair[1].makeReturn();
+ }
+ if ((_ref3 = this.otherwise) != null) {
+ _ref3.makeReturn();
+ }
+ return this;
+ };
+ Switch.prototype.compileNode = function(o) {
+ var block, body, code, cond, conditions, expr, i, idt1, idt2, _i, _len, _len2, _ref2, _ref3, _ref4, _ref5;
+ idt1 = o.indent + TAB;
+ idt2 = o.indent = idt1 + TAB;
+ code = this.tab + ("switch (" + (((_ref2 = this.subject) != null ? _ref2.compile(o, LEVEL_PAREN) : void 0) || false) + ") {\n");
+ _ref3 = this.cases;
+ for (i = 0, _len = _ref3.length; i < _len; i++) {
+ _ref4 = _ref3[i], conditions = _ref4[0], block = _ref4[1];
+ _ref5 = flatten([conditions]);
+ for (_i = 0, _len2 = _ref5.length; _i < _len2; _i++) {
+ cond = _ref5[_i];
+ if (!this.subject) {
+ cond = cond.invert();
+ }
+ code += idt1 + ("case " + (cond.compile(o, LEVEL_PAREN)) + ":\n");
+ }
+ if (body = block.compile(o, LEVEL_TOP)) {
+ code += body + '\n';
+ }
+ if (i === this.cases.length - 1 && !this.otherwise) {
+ break;
+ }
+ expr = this.lastNonComment(block.expressions);
+ if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) {
+ continue;
+ }
+ code += idt2 + 'break;\n';
+ }
+ if (this.otherwise && this.otherwise.expressions.length) {
+ code += idt1 + ("default:\n" + (this.otherwise.compile(o, LEVEL_TOP)) + "\n");
+ }
+ return code + this.tab + '}';
+ };
+ return Switch;
+ })();
+ exports.If = If = (function() {
+ __extends(If, Base);
+ function If(condition, body, options) {
+ this.body = body;
+ if (options == null) {
+ options = {};
+ }
+ this.condition = options.type === 'unless' ? condition.invert() : condition;
+ this.elseBody = null;
+ this.isChain = false;
+ this.soak = options.soak;
+ }
+ If.prototype.children = ['condition', 'body', 'elseBody'];
+ If.prototype.bodyNode = function() {
+ var _ref2;
+ return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0;
+ };
+ If.prototype.elseBodyNode = function() {
+ var _ref2;
+ return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0;
+ };
+ If.prototype.addElse = function(elseBody) {
+ if (this.isChain) {
+ this.elseBodyNode().addElse(elseBody);
+ } else {
+ this.isChain = elseBody instanceof If;
+ this.elseBody = this.ensureBlock(elseBody);
+ }
+ return this;
+ };
+ If.prototype.isStatement = function(o) {
+ var _ref2;
+ return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0);
+ };
+ If.prototype.jumps = function(o) {
+ var _ref2;
+ return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0);
+ };
+ If.prototype.compileNode = function(o) {
+ if (this.isStatement(o)) {
+ return this.compileStatement(o);
+ } else {
+ return this.compileExpression(o);
+ }
+ };
+ If.prototype.makeReturn = function() {
+ this.body && (this.body = new Block([this.body.makeReturn()]));
+ this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn()]));
+ return this;
+ };
+ If.prototype.ensureBlock = function(node) {
+ if (node instanceof Block) {
+ return node;
+ } else {
+ return new Block([node]);
+ }
+ };
+ If.prototype.compileStatement = function(o) {
+ var body, child, cond, exeq, ifPart;
+ child = del(o, 'chainChild');
+ exeq = del(o, 'isExistentialEquals');
+ if (exeq) {
+ return new If(this.condition.invert(), this.elseBodyNode(), {
+ type: 'if'
+ }).compile(o);
+ }
+ cond = this.condition.compile(o, LEVEL_PAREN);
+ o.indent += TAB;
+ body = this.ensureBlock(this.body).compile(o);
+ if (body) {
+ body = "\n" + body + "\n" + this.tab;
+ }
+ ifPart = "if (" + cond + ") {" + body + "}";
+ if (!child) {
+ ifPart = this.tab + ifPart;
+ }
+ if (!this.elseBody) {
+ return ifPart;
+ }
+ return ifPart + ' else ' + (this.isChain ? (o.indent = this.tab, o.chainChild = true, this.elseBody.unwrap().compile(o, LEVEL_TOP)) : "{\n" + (this.elseBody.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}");
+ };
+ If.prototype.compileExpression = function(o) {
+ var alt, body, code, cond;
+ cond = this.condition.compile(o, LEVEL_COND);
+ body = this.bodyNode().compile(o, LEVEL_LIST);
+ alt = this.elseBodyNode() ? this.elseBodyNode().compile(o, LEVEL_LIST) : 'void 0';
+ code = "" + cond + " ? " + body + " : " + alt;
+ if (o.level >= LEVEL_COND) {
+ return "(" + code + ")";
+ } else {
+ return code;
+ }
+ };
+ If.prototype.unfoldSoak = function() {
+ return this.soak && this;
+ };
+ return If;
+ })();
+ Push = {
+ wrap: function(name, exps) {
+ if (exps.isEmpty() || last(exps.expressions).jumps()) {
+ return exps;
+ }
+ return exps.push(new Call(new Value(new Literal(name), [new Access(new Literal('push'))]), [exps.pop()]));
+ }
+ };
+ Closure = {
+ wrap: function(expressions, statement, noReturn) {
+ var args, call, func, mentionsArgs, meth;
+ if (expressions.jumps()) {
+ return expressions;
+ }
+ func = new Code([], Block.wrap([expressions]));
+ args = [];
+ if ((mentionsArgs = expressions.contains(this.literalArgs)) || expressions.contains(this.literalThis)) {
+ meth = new Literal(mentionsArgs ? 'apply' : 'call');
+ args = [new Literal('this')];
+ if (mentionsArgs) {
+ args.push(new Literal('arguments'));
+ }
+ func = new Value(func, [new Access(meth)]);
+ }
+ func.noReturn = noReturn;
+ call = new Call(func, args);
+ if (statement) {
+ return Block.wrap([call]);
+ } else {
+ return call;
+ }
+ },
+ literalArgs: function(node) {
+ return node instanceof Literal && node.value === 'arguments' && !node.asKey;
+ },
+ literalThis: function(node) {
+ return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound);
+ }
+ };
+ unfoldSoak = function(o, parent, name) {
+ var ifn;
+ if (!(ifn = parent[name].unfoldSoak(o))) {
+ return;
+ }
+ parent[name] = ifn.body;
+ ifn.body = new Value(parent);
+ return ifn;
+ };
+ UTILITIES = {
+ "extends": 'function(child, parent) {\n for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }\n function ctor() { this.constructor = child; }\n ctor.prototype = parent.prototype;\n child.prototype = new ctor;\n child.__super__ = parent.prototype;\n return child;\n}',
+ bind: 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }',
+ indexOf: 'Array.prototype.indexOf || function(item) {\n for (var i = 0, l = this.length; i < l; i++) {\n if (this[i] === item) return i;\n }\n return -1;\n}',
+ hasProp: 'Object.prototype.hasOwnProperty',
+ slice: 'Array.prototype.slice'
+ };
+ LEVEL_TOP = 1;
+ LEVEL_PAREN = 2;
+ LEVEL_LIST = 3;
+ LEVEL_COND = 4;
+ LEVEL_OP = 5;
+ LEVEL_ACCESS = 6;
+ TAB = ' ';
+ IDENTIFIER = /^[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*$/;
+ SIMPLENUM = /^[+-]?\d+$/;
+ METHOD_DEF = /^(?:([$A-Za-z_][$\w\x7f-\uffff]*)\.prototype\.)?([$A-Za-z_][$\w\x7f-\uffff]*)$/;
+ IS_STRING = /^['"]/;
+ utility = function(name) {
+ var ref;
+ ref = "__" + name;
+ Scope.root.assign(ref, UTILITIES[name]);
+ return ref;
+ };
+ multident = function(code, tab) {
+ return code.replace(/\n/g, '$&' + tab);
+ };
+});
diff --git a/ace/mode/coffee/parser.js b/ace/mode/coffee/parser.js
new file mode 100644
index 00000000..8f90c442
--- /dev/null
+++ b/ace/mode/coffee/parser.js
@@ -0,0 +1,685 @@
+/**
+ * Copyright (c) 2011 Jeremy Ashkenas
+ *
+ * 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.
+ */
+
+define(function(require, exports, module) {
+
+/* Jison generated parser */
+var parser = {trace: function trace() { },
+yy: {},
+symbols_: {"error":2,"Root":3,"Body":4,"Block":5,"TERMINATOR":6,"Line":7,"Expression":8,"Statement":9,"Return":10,"Throw":11,"Comment":12,"STATEMENT":13,"Value":14,"Invocation":15,"Code":16,"Operation":17,"Assign":18,"If":19,"Try":20,"While":21,"For":22,"Switch":23,"Class":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"BOOL":35,"Assignable":36,"=":37,"AssignObj":38,"ObjAssignable":39,":":40,"ThisProperty":41,"RETURN":42,"HERECOMMENT":43,"PARAM_START":44,"ParamList":45,"PARAM_END":46,"FuncGlyph":47,"->":48,"=>":49,"OptComma":50,",":51,"Param":52,"ParamVar":53,"...":54,"Array":55,"Object":56,"Splat":57,"SimpleAssignable":58,"Accessor":59,"Parenthetical":60,"Range":61,"This":62,".":63,"?.":64,"::":65,"Index":66,"INDEX_START":67,"IndexValue":68,"INDEX_END":69,"INDEX_SOAK":70,"INDEX_PROTO":71,"Slice":72,"{":73,"AssignList":74,"}":75,"CLASS":76,"EXTENDS":77,"OptFuncExist":78,"Arguments":79,"SUPER":80,"FUNC_EXIST":81,"CALL_START":82,"CALL_END":83,"ArgList":84,"THIS":85,"@":86,"[":87,"]":88,"RangeDots":89,"..":90,"Arg":91,"SimpleArgs":92,"TRY":93,"Catch":94,"FINALLY":95,"CATCH":96,"THROW":97,"(":98,")":99,"WhileSource":100,"WHILE":101,"WHEN":102,"UNTIL":103,"Loop":104,"LOOP":105,"ForBody":106,"FOR":107,"ForStart":108,"ForSource":109,"ForVariables":110,"OWN":111,"ForValue":112,"FORIN":113,"FOROF":114,"BY":115,"SWITCH":116,"Whens":117,"ELSE":118,"When":119,"LEADING_WHEN":120,"IfBlock":121,"IF":122,"POST_IF":123,"UNARY":124,"-":125,"+":126,"--":127,"++":128,"?":129,"MATH":130,"SHIFT":131,"COMPARE":132,"LOGIC":133,"RELATION":134,"COMPOUND_ASSIGN":135,"$accept":0,"$end":1},
+terminals_: {2:"error",6:"TERMINATOR",13:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",31:"STRING",33:"JS",34:"REGEX",35:"BOOL",37:"=",40:":",42:"RETURN",43:"HERECOMMENT",44:"PARAM_START",46:"PARAM_END",48:"->",49:"=>",51:",",54:"...",63:".",64:"?.",65:"::",67:"INDEX_START",69:"INDEX_END",70:"INDEX_SOAK",71:"INDEX_PROTO",73:"{",75:"}",76:"CLASS",77:"EXTENDS",80:"SUPER",81:"FUNC_EXIST",82:"CALL_START",83:"CALL_END",85:"THIS",86:"@",87:"[",88:"]",90:"..",93:"TRY",95:"FINALLY",96:"CATCH",97:"THROW",98:"(",99:")",101:"WHILE",102:"WHEN",103:"UNTIL",105:"LOOP",107:"FOR",111:"OWN",113:"FORIN",114:"FOROF",115:"BY",116:"SWITCH",118:"ELSE",120:"LEADING_WHEN",122:"IF",123:"POST_IF",124:"UNARY",125:"-",126:"+",127:"--",128:"++",129:"?",130:"MATH",131:"SHIFT",132:"COMPARE",133:"LOGIC",134:"RELATION",135:"COMPOUND_ASSIGN"},
+productions_: [0,[3,0],[3,1],[3,2],[4,1],[4,3],[4,2],[7,1],[7,1],[9,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[5,2],[5,3],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[18,3],[18,5],[38,1],[38,3],[38,5],[38,1],[39,1],[39,1],[39,1],[10,2],[10,1],[12,1],[16,5],[16,2],[47,1],[47,1],[50,0],[50,1],[45,0],[45,1],[45,3],[52,1],[52,2],[52,3],[53,1],[53,1],[53,1],[53,1],[57,2],[58,1],[58,2],[58,2],[58,1],[36,1],[36,1],[36,1],[14,1],[14,1],[14,1],[14,1],[14,1],[59,2],[59,2],[59,2],[59,1],[59,1],[66,3],[66,2],[66,2],[68,1],[68,1],[56,4],[74,0],[74,1],[74,3],[74,4],[74,6],[24,1],[24,2],[24,3],[24,4],[24,2],[24,3],[24,4],[24,5],[15,3],[15,3],[15,1],[15,2],[78,0],[78,1],[79,2],[79,4],[62,1],[62,1],[41,2],[55,2],[55,4],[89,1],[89,1],[61,5],[72,3],[72,2],[72,2],[84,1],[84,3],[84,4],[84,4],[84,6],[91,1],[91,1],[92,1],[92,3],[20,2],[20,3],[20,4],[20,5],[94,3],[11,2],[60,3],[60,5],[100,2],[100,4],[100,2],[100,4],[21,2],[21,2],[21,2],[21,1],[104,2],[104,2],[22,2],[22,2],[22,2],[106,2],[106,2],[108,2],[108,3],[112,1],[112,1],[112,1],[110,1],[110,3],[109,2],[109,2],[109,4],[109,4],[109,4],[109,6],[109,6],[23,5],[23,7],[23,4],[23,6],[117,1],[117,2],[119,3],[119,4],[121,3],[121,5],[19,1],[19,3],[19,3],[19,3],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,2],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,3],[17,5],[17,3]],
+performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
+
+var $0 = $$.length - 1;
+switch (yystate) {
+case 1:return this.$ = new yy.Block;
+break;
+case 2:return this.$ = $$[$0];
+break;
+case 3:return this.$ = $$[$0-1];
+break;
+case 4:this.$ = yy.Block.wrap([$$[$0]]);
+break;
+case 5:this.$ = $$[$0-2].push($$[$0]);
+break;
+case 6:this.$ = $$[$0-1];
+break;
+case 7:this.$ = $$[$0];
+break;
+case 8:this.$ = $$[$0];
+break;
+case 9:this.$ = $$[$0];
+break;
+case 10:this.$ = $$[$0];
+break;
+case 11:this.$ = $$[$0];
+break;
+case 12:this.$ = new yy.Literal($$[$0]);
+break;
+case 13:this.$ = $$[$0];
+break;
+case 14:this.$ = $$[$0];
+break;
+case 15:this.$ = $$[$0];
+break;
+case 16:this.$ = $$[$0];
+break;
+case 17:this.$ = $$[$0];
+break;
+case 18:this.$ = $$[$0];
+break;
+case 19:this.$ = $$[$0];
+break;
+case 20:this.$ = $$[$0];
+break;
+case 21:this.$ = $$[$0];
+break;
+case 22:this.$ = $$[$0];
+break;
+case 23:this.$ = $$[$0];
+break;
+case 24:this.$ = new yy.Block;
+break;
+case 25:this.$ = $$[$0-1];
+break;
+case 26:this.$ = new yy.Literal($$[$0]);
+break;
+case 27:this.$ = new yy.Literal($$[$0]);
+break;
+case 28:this.$ = new yy.Literal($$[$0]);
+break;
+case 29:this.$ = $$[$0];
+break;
+case 30:this.$ = new yy.Literal($$[$0]);
+break;
+case 31:this.$ = new yy.Literal($$[$0]);
+break;
+case 32:this.$ = (function () {
+ var val;
+ val = new yy.Literal($$[$0]);
+ if ($$[$0] === 'undefined') {
+ val.isUndefined = true;
+ }
+ return val;
+ }());
+break;
+case 33:this.$ = new yy.Assign($$[$0-2], $$[$0]);
+break;
+case 34:this.$ = new yy.Assign($$[$0-4], $$[$0-1]);
+break;
+case 35:this.$ = new yy.Value($$[$0]);
+break;
+case 36:this.$ = new yy.Assign(new yy.Value($$[$0-2]), $$[$0], 'object');
+break;
+case 37:this.$ = new yy.Assign(new yy.Value($$[$0-4]), $$[$0-1], 'object');
+break;
+case 38:this.$ = $$[$0];
+break;
+case 39:this.$ = $$[$0];
+break;
+case 40:this.$ = $$[$0];
+break;
+case 41:this.$ = $$[$0];
+break;
+case 42:this.$ = new yy.Return($$[$0]);
+break;
+case 43:this.$ = new yy.Return;
+break;
+case 44:this.$ = new yy.Comment($$[$0]);
+break;
+case 45:this.$ = new yy.Code($$[$0-3], $$[$0], $$[$0-1]);
+break;
+case 46:this.$ = new yy.Code([], $$[$0], $$[$0-1]);
+break;
+case 47:this.$ = 'func';
+break;
+case 48:this.$ = 'boundfunc';
+break;
+case 49:this.$ = $$[$0];
+break;
+case 50:this.$ = $$[$0];
+break;
+case 51:this.$ = [];
+break;
+case 52:this.$ = [$$[$0]];
+break;
+case 53:this.$ = $$[$0-2].concat($$[$0]);
+break;
+case 54:this.$ = new yy.Param($$[$0]);
+break;
+case 55:this.$ = new yy.Param($$[$0-1], null, true);
+break;
+case 56:this.$ = new yy.Param($$[$0-2], $$[$0]);
+break;
+case 57:this.$ = $$[$0];
+break;
+case 58:this.$ = $$[$0];
+break;
+case 59:this.$ = $$[$0];
+break;
+case 60:this.$ = $$[$0];
+break;
+case 61:this.$ = new yy.Splat($$[$0-1]);
+break;
+case 62:this.$ = new yy.Value($$[$0]);
+break;
+case 63:this.$ = $$[$0-1].push($$[$0]);
+break;
+case 64:this.$ = new yy.Value($$[$0-1], [$$[$0]]);
+break;
+case 65:this.$ = $$[$0];
+break;
+case 66:this.$ = $$[$0];
+break;
+case 67:this.$ = new yy.Value($$[$0]);
+break;
+case 68:this.$ = new yy.Value($$[$0]);
+break;
+case 69:this.$ = $$[$0];
+break;
+case 70:this.$ = new yy.Value($$[$0]);
+break;
+case 71:this.$ = new yy.Value($$[$0]);
+break;
+case 72:this.$ = new yy.Value($$[$0]);
+break;
+case 73:this.$ = $$[$0];
+break;
+case 74:this.$ = new yy.Access($$[$0]);
+break;
+case 75:this.$ = new yy.Access($$[$0], 'soak');
+break;
+case 76:this.$ = new yy.Access($$[$0], 'proto');
+break;
+case 77:this.$ = new yy.Access(new yy.Literal('prototype'));
+break;
+case 78:this.$ = $$[$0];
+break;
+case 79:this.$ = $$[$0-1];
+break;
+case 80:this.$ = yy.extend($$[$0], {
+ soak: true
+ });
+break;
+case 81:this.$ = yy.extend($$[$0], {
+ proto: true
+ });
+break;
+case 82:this.$ = new yy.Index($$[$0]);
+break;
+case 83:this.$ = new yy.Slice($$[$0]);
+break;
+case 84:this.$ = new yy.Obj($$[$0-2], $$[$0-3].generated);
+break;
+case 85:this.$ = [];
+break;
+case 86:this.$ = [$$[$0]];
+break;
+case 87:this.$ = $$[$0-2].concat($$[$0]);
+break;
+case 88:this.$ = $$[$0-3].concat($$[$0]);
+break;
+case 89:this.$ = $$[$0-5].concat($$[$0-2]);
+break;
+case 90:this.$ = new yy.Class;
+break;
+case 91:this.$ = new yy.Class(null, null, $$[$0]);
+break;
+case 92:this.$ = new yy.Class(null, $$[$0]);
+break;
+case 93:this.$ = new yy.Class(null, $$[$0-1], $$[$0]);
+break;
+case 94:this.$ = new yy.Class($$[$0]);
+break;
+case 95:this.$ = new yy.Class($$[$0-1], null, $$[$0]);
+break;
+case 96:this.$ = new yy.Class($$[$0-2], $$[$0]);
+break;
+case 97:this.$ = new yy.Class($$[$0-3], $$[$0-1], $$[$0]);
+break;
+case 98:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]);
+break;
+case 99:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]);
+break;
+case 100:this.$ = new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]);
+break;
+case 101:this.$ = new yy.Call('super', $$[$0]);
+break;
+case 102:this.$ = false;
+break;
+case 103:this.$ = true;
+break;
+case 104:this.$ = [];
+break;
+case 105:this.$ = $$[$0-2];
+break;
+case 106:this.$ = new yy.Value(new yy.Literal('this'));
+break;
+case 107:this.$ = new yy.Value(new yy.Literal('this'));
+break;
+case 108:this.$ = new yy.Value(new yy.Literal('this'), [new yy.Access($$[$0])], 'this');
+break;
+case 109:this.$ = new yy.Arr([]);
+break;
+case 110:this.$ = new yy.Arr($$[$0-2]);
+break;
+case 111:this.$ = 'inclusive';
+break;
+case 112:this.$ = 'exclusive';
+break;
+case 113:this.$ = new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]);
+break;
+case 114:this.$ = new yy.Range($$[$0-2], $$[$0], $$[$0-1]);
+break;
+case 115:this.$ = new yy.Range($$[$0-1], null, $$[$0]);
+break;
+case 116:this.$ = new yy.Range(null, $$[$0], $$[$0-1]);
+break;
+case 117:this.$ = [$$[$0]];
+break;
+case 118:this.$ = $$[$0-2].concat($$[$0]);
+break;
+case 119:this.$ = $$[$0-3].concat($$[$0]);
+break;
+case 120:this.$ = $$[$0-2];
+break;
+case 121:this.$ = $$[$0-5].concat($$[$0-2]);
+break;
+case 122:this.$ = $$[$0];
+break;
+case 123:this.$ = $$[$0];
+break;
+case 124:this.$ = $$[$0];
+break;
+case 125:this.$ = [].concat($$[$0-2], $$[$0]);
+break;
+case 126:this.$ = new yy.Try($$[$0]);
+break;
+case 127:this.$ = new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]);
+break;
+case 128:this.$ = new yy.Try($$[$0-2], null, null, $$[$0]);
+break;
+case 129:this.$ = new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]);
+break;
+case 130:this.$ = [$$[$0-1], $$[$0]];
+break;
+case 131:this.$ = new yy.Throw($$[$0]);
+break;
+case 132:this.$ = new yy.Parens($$[$0-1]);
+break;
+case 133:this.$ = new yy.Parens($$[$0-2]);
+break;
+case 134:this.$ = new yy.While($$[$0]);
+break;
+case 135:this.$ = new yy.While($$[$0-2], {
+ guard: $$[$0]
+ });
+break;
+case 136:this.$ = new yy.While($$[$0], {
+ invert: true
+ });
+break;
+case 137:this.$ = new yy.While($$[$0-2], {
+ invert: true,
+ guard: $$[$0]
+ });
+break;
+case 138:this.$ = $$[$0-1].addBody($$[$0]);
+break;
+case 139:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]]));
+break;
+case 140:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]]));
+break;
+case 141:this.$ = $$[$0];
+break;
+case 142:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0]);
+break;
+case 143:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Block.wrap([$$[$0]]));
+break;
+case 144:this.$ = new yy.For($$[$0-1], $$[$0]);
+break;
+case 145:this.$ = new yy.For($$[$0-1], $$[$0]);
+break;
+case 146:this.$ = new yy.For($$[$0], $$[$0-1]);
+break;
+case 147:this.$ = {
+ source: new yy.Value($$[$0])
+ };
+break;
+case 148:this.$ = (function () {
+ $$[$0].own = $$[$0-1].own;
+ $$[$0].name = $$[$0-1][0];
+ $$[$0].index = $$[$0-1][1];
+ return $$[$0];
+ }());
+break;
+case 149:this.$ = $$[$0];
+break;
+case 150:this.$ = (function () {
+ $$[$0].own = true;
+ return $$[$0];
+ }());
+break;
+case 151:this.$ = $$[$0];
+break;
+case 152:this.$ = new yy.Value($$[$0]);
+break;
+case 153:this.$ = new yy.Value($$[$0]);
+break;
+case 154:this.$ = [$$[$0]];
+break;
+case 155:this.$ = [$$[$0-2], $$[$0]];
+break;
+case 156:this.$ = {
+ source: $$[$0]
+ };
+break;
+case 157:this.$ = {
+ source: $$[$0],
+ object: true
+ };
+break;
+case 158:this.$ = {
+ source: $$[$0-2],
+ guard: $$[$0]
+ };
+break;
+case 159:this.$ = {
+ source: $$[$0-2],
+ guard: $$[$0],
+ object: true
+ };
+break;
+case 160:this.$ = {
+ source: $$[$0-2],
+ step: $$[$0]
+ };
+break;
+case 161:this.$ = {
+ source: $$[$0-4],
+ guard: $$[$0-2],
+ step: $$[$0]
+ };
+break;
+case 162:this.$ = {
+ source: $$[$0-4],
+ step: $$[$0-2],
+ guard: $$[$0]
+ };
+break;
+case 163:this.$ = new yy.Switch($$[$0-3], $$[$0-1]);
+break;
+case 164:this.$ = new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]);
+break;
+case 165:this.$ = new yy.Switch(null, $$[$0-1]);
+break;
+case 166:this.$ = new yy.Switch(null, $$[$0-3], $$[$0-1]);
+break;
+case 167:this.$ = $$[$0];
+break;
+case 168:this.$ = $$[$0-1].concat($$[$0]);
+break;
+case 169:this.$ = [[$$[$0-1], $$[$0]]];
+break;
+case 170:this.$ = [[$$[$0-2], $$[$0-1]]];
+break;
+case 171:this.$ = new yy.If($$[$0-1], $$[$0], {
+ type: $$[$0-2]
+ });
+break;
+case 172:this.$ = $$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], {
+ type: $$[$0-2]
+ }));
+break;
+case 173:this.$ = $$[$0];
+break;
+case 174:this.$ = $$[$0-2].addElse($$[$0]);
+break;
+case 175:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), {
+ type: $$[$0-1],
+ statement: true
+ });
+break;
+case 176:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), {
+ type: $$[$0-1],
+ statement: true
+ });
+break;
+case 177:this.$ = new yy.Op($$[$0-1], $$[$0]);
+break;
+case 178:this.$ = new yy.Op('-', $$[$0]);
+break;
+case 179:this.$ = new yy.Op('+', $$[$0]);
+break;
+case 180:this.$ = new yy.Op('--', $$[$0]);
+break;
+case 181:this.$ = new yy.Op('++', $$[$0]);
+break;
+case 182:this.$ = new yy.Op('--', $$[$0-1], null, true);
+break;
+case 183:this.$ = new yy.Op('++', $$[$0-1], null, true);
+break;
+case 184:this.$ = new yy.Existence($$[$0-1]);
+break;
+case 185:this.$ = new yy.Op('+', $$[$0-2], $$[$0]);
+break;
+case 186:this.$ = new yy.Op('-', $$[$0-2], $$[$0]);
+break;
+case 187:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
+break;
+case 188:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
+break;
+case 189:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
+break;
+case 190:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
+break;
+case 191:this.$ = (function () {
+ if ($$[$0-1].charAt(0) === '!') {
+ return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
+ } else {
+ return new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
+ }
+ }());
+break;
+case 192:this.$ = new yy.Assign($$[$0-2], $$[$0], $$[$0-1]);
+break;
+case 193:this.$ = new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]);
+break;
+case 194:this.$ = new yy.Extends($$[$0-2], $$[$0]);
+break;
+}
+},
+table: [{1:[2,1],3:1,4:2,5:3,7:4,8:6,9:7,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,5],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[3]},{1:[2,2],6:[1,71]},{6:[1,72]},{1:[2,4],6:[2,4],26:[2,4],99:[2,4]},{4:74,7:4,8:6,9:7,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,26:[1,73],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,7],6:[2,7],26:[2,7],99:[2,7],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,8],6:[2,8],26:[2,8],99:[2,8],100:87,101:[1,62],103:[1,63],106:88,107:[1,65],108:66,123:[1,86]},{1:[2,13],6:[2,13],25:[2,13],26:[2,13],46:[2,13],51:[2,13],54:[2,13],59:90,63:[1,92],64:[1,93],65:[1,94],66:95,67:[1,96],69:[2,13],70:[1,97],71:[1,98],75:[2,13],78:89,81:[1,91],82:[2,102],83:[2,13],88:[2,13],90:[2,13],99:[2,13],101:[2,13],102:[2,13],103:[2,13],107:[2,13],115:[2,13],123:[2,13],125:[2,13],126:[2,13],129:[2,13],130:[2,13],131:[2,13],132:[2,13],133:[2,13],134:[2,13]},{1:[2,14],6:[2,14],25:[2,14],26:[2,14],46:[2,14],51:[2,14],54:[2,14],59:100,63:[1,92],64:[1,93],65:[1,94],66:95,67:[1,96],69:[2,14],70:[1,97],71:[1,98],75:[2,14],78:99,81:[1,91],82:[2,102],83:[2,14],88:[2,14],90:[2,14],99:[2,14],101:[2,14],102:[2,14],103:[2,14],107:[2,14],115:[2,14],123:[2,14],125:[2,14],126:[2,14],129:[2,14],130:[2,14],131:[2,14],132:[2,14],133:[2,14],134:[2,14]},{1:[2,15],6:[2,15],25:[2,15],26:[2,15],46:[2,15],51:[2,15],54:[2,15],69:[2,15],75:[2,15],83:[2,15],88:[2,15],90:[2,15],99:[2,15],101:[2,15],102:[2,15],103:[2,15],107:[2,15],115:[2,15],123:[2,15],125:[2,15],126:[2,15],129:[2,15],130:[2,15],131:[2,15],132:[2,15],133:[2,15],134:[2,15]},{1:[2,16],6:[2,16],25:[2,16],26:[2,16],46:[2,16],51:[2,16],54:[2,16],69:[2,16],75:[2,16],83:[2,16],88:[2,16],90:[2,16],99:[2,16],101:[2,16],102:[2,16],103:[2,16],107:[2,16],115:[2,16],123:[2,16],125:[2,16],126:[2,16],129:[2,16],130:[2,16],131:[2,16],132:[2,16],133:[2,16],134:[2,16]},{1:[2,17],6:[2,17],25:[2,17],26:[2,17],46:[2,17],51:[2,17],54:[2,17],69:[2,17],75:[2,17],83:[2,17],88:[2,17],90:[2,17],99:[2,17],101:[2,17],102:[2,17],103:[2,17],107:[2,17],115:[2,17],123:[2,17],125:[2,17],126:[2,17],129:[2,17],130:[2,17],131:[2,17],132:[2,17],133:[2,17],134:[2,17]},{1:[2,18],6:[2,18],25:[2,18],26:[2,18],46:[2,18],51:[2,18],54:[2,18],69:[2,18],75:[2,18],83:[2,18],88:[2,18],90:[2,18],99:[2,18],101:[2,18],102:[2,18],103:[2,18],107:[2,18],115:[2,18],123:[2,18],125:[2,18],126:[2,18],129:[2,18],130:[2,18],131:[2,18],132:[2,18],133:[2,18],134:[2,18]},{1:[2,19],6:[2,19],25:[2,19],26:[2,19],46:[2,19],51:[2,19],54:[2,19],69:[2,19],75:[2,19],83:[2,19],88:[2,19],90:[2,19],99:[2,19],101:[2,19],102:[2,19],103:[2,19],107:[2,19],115:[2,19],123:[2,19],125:[2,19],126:[2,19],129:[2,19],130:[2,19],131:[2,19],132:[2,19],133:[2,19],134:[2,19]},{1:[2,20],6:[2,20],25:[2,20],26:[2,20],46:[2,20],51:[2,20],54:[2,20],69:[2,20],75:[2,20],83:[2,20],88:[2,20],90:[2,20],99:[2,20],101:[2,20],102:[2,20],103:[2,20],107:[2,20],115:[2,20],123:[2,20],125:[2,20],126:[2,20],129:[2,20],130:[2,20],131:[2,20],132:[2,20],133:[2,20],134:[2,20]},{1:[2,21],6:[2,21],25:[2,21],26:[2,21],46:[2,21],51:[2,21],54:[2,21],69:[2,21],75:[2,21],83:[2,21],88:[2,21],90:[2,21],99:[2,21],101:[2,21],102:[2,21],103:[2,21],107:[2,21],115:[2,21],123:[2,21],125:[2,21],126:[2,21],129:[2,21],130:[2,21],131:[2,21],132:[2,21],133:[2,21],134:[2,21]},{1:[2,22],6:[2,22],25:[2,22],26:[2,22],46:[2,22],51:[2,22],54:[2,22],69:[2,22],75:[2,22],83:[2,22],88:[2,22],90:[2,22],99:[2,22],101:[2,22],102:[2,22],103:[2,22],107:[2,22],115:[2,22],123:[2,22],125:[2,22],126:[2,22],129:[2,22],130:[2,22],131:[2,22],132:[2,22],133:[2,22],134:[2,22]},{1:[2,23],6:[2,23],25:[2,23],26:[2,23],46:[2,23],51:[2,23],54:[2,23],69:[2,23],75:[2,23],83:[2,23],88:[2,23],90:[2,23],99:[2,23],101:[2,23],102:[2,23],103:[2,23],107:[2,23],115:[2,23],123:[2,23],125:[2,23],126:[2,23],129:[2,23],130:[2,23],131:[2,23],132:[2,23],133:[2,23],134:[2,23]},{1:[2,9],6:[2,9],26:[2,9],99:[2,9],101:[2,9],103:[2,9],107:[2,9],123:[2,9]},{1:[2,10],6:[2,10],26:[2,10],99:[2,10],101:[2,10],103:[2,10],107:[2,10],123:[2,10]},{1:[2,11],6:[2,11],26:[2,11],99:[2,11],101:[2,11],103:[2,11],107:[2,11],123:[2,11]},{1:[2,12],6:[2,12],26:[2,12],99:[2,12],101:[2,12],103:[2,12],107:[2,12],123:[2,12]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],37:[1,101],46:[2,69],51:[2,69],54:[2,69],63:[2,69],64:[2,69],65:[2,69],67:[2,69],69:[2,69],70:[2,69],71:[2,69],75:[2,69],81:[2,69],82:[2,69],83:[2,69],88:[2,69],90:[2,69],99:[2,69],101:[2,69],102:[2,69],103:[2,69],107:[2,69],115:[2,69],123:[2,69],125:[2,69],126:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69]},{1:[2,70],6:[2,70],25:[2,70],26:[2,70],46:[2,70],51:[2,70],54:[2,70],63:[2,70],64:[2,70],65:[2,70],67:[2,70],69:[2,70],70:[2,70],71:[2,70],75:[2,70],81:[2,70],82:[2,70],83:[2,70],88:[2,70],90:[2,70],99:[2,70],101:[2,70],102:[2,70],103:[2,70],107:[2,70],115:[2,70],123:[2,70],125:[2,70],126:[2,70],129:[2,70],130:[2,70],131:[2,70],132:[2,70],133:[2,70],134:[2,70]},{1:[2,71],6:[2,71],25:[2,71],26:[2,71],46:[2,71],51:[2,71],54:[2,71],63:[2,71],64:[2,71],65:[2,71],67:[2,71],69:[2,71],70:[2,71],71:[2,71],75:[2,71],81:[2,71],82:[2,71],83:[2,71],88:[2,71],90:[2,71],99:[2,71],101:[2,71],102:[2,71],103:[2,71],107:[2,71],115:[2,71],123:[2,71],125:[2,71],126:[2,71],129:[2,71],130:[2,71],131:[2,71],132:[2,71],133:[2,71],134:[2,71]},{1:[2,72],6:[2,72],25:[2,72],26:[2,72],46:[2,72],51:[2,72],54:[2,72],63:[2,72],64:[2,72],65:[2,72],67:[2,72],69:[2,72],70:[2,72],71:[2,72],75:[2,72],81:[2,72],82:[2,72],83:[2,72],88:[2,72],90:[2,72],99:[2,72],101:[2,72],102:[2,72],103:[2,72],107:[2,72],115:[2,72],123:[2,72],125:[2,72],126:[2,72],129:[2,72],130:[2,72],131:[2,72],132:[2,72],133:[2,72],134:[2,72]},{1:[2,73],6:[2,73],25:[2,73],26:[2,73],46:[2,73],51:[2,73],54:[2,73],63:[2,73],64:[2,73],65:[2,73],67:[2,73],69:[2,73],70:[2,73],71:[2,73],75:[2,73],81:[2,73],82:[2,73],83:[2,73],88:[2,73],90:[2,73],99:[2,73],101:[2,73],102:[2,73],103:[2,73],107:[2,73],115:[2,73],123:[2,73],125:[2,73],126:[2,73],129:[2,73],130:[2,73],131:[2,73],132:[2,73],133:[2,73],134:[2,73]},{1:[2,100],6:[2,100],25:[2,100],26:[2,100],46:[2,100],51:[2,100],54:[2,100],63:[2,100],64:[2,100],65:[2,100],67:[2,100],69:[2,100],70:[2,100],71:[2,100],75:[2,100],79:102,81:[2,100],82:[1,103],83:[2,100],88:[2,100],90:[2,100],99:[2,100],101:[2,100],102:[2,100],103:[2,100],107:[2,100],115:[2,100],123:[2,100],125:[2,100],126:[2,100],129:[2,100],130:[2,100],131:[2,100],132:[2,100],133:[2,100],134:[2,100]},{27:107,28:[1,70],41:108,45:104,46:[2,51],51:[2,51],52:105,53:106,55:109,56:110,73:[1,67],86:[1,111],87:[1,112]},{5:113,25:[1,5]},{8:114,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:116,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:117,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{14:119,15:120,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:121,41:60,55:47,56:48,58:118,60:25,61:26,62:27,73:[1,67],80:[1,28],85:[1,55],86:[1,56],87:[1,54],98:[1,53]},{14:119,15:120,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:121,41:60,55:47,56:48,58:122,60:25,61:26,62:27,73:[1,67],80:[1,28],85:[1,55],86:[1,56],87:[1,54],98:[1,53]},{1:[2,66],6:[2,66],25:[2,66],26:[2,66],37:[2,66],46:[2,66],51:[2,66],54:[2,66],63:[2,66],64:[2,66],65:[2,66],67:[2,66],69:[2,66],70:[2,66],71:[2,66],75:[2,66],77:[1,126],81:[2,66],82:[2,66],83:[2,66],88:[2,66],90:[2,66],99:[2,66],101:[2,66],102:[2,66],103:[2,66],107:[2,66],115:[2,66],123:[2,66],125:[2,66],126:[2,66],127:[1,123],128:[1,124],129:[2,66],130:[2,66],131:[2,66],132:[2,66],133:[2,66],134:[2,66],135:[1,125]},{1:[2,173],6:[2,173],25:[2,173],26:[2,173],46:[2,173],51:[2,173],54:[2,173],69:[2,173],75:[2,173],83:[2,173],88:[2,173],90:[2,173],99:[2,173],101:[2,173],102:[2,173],103:[2,173],107:[2,173],115:[2,173],118:[1,127],123:[2,173],125:[2,173],126:[2,173],129:[2,173],130:[2,173],131:[2,173],132:[2,173],133:[2,173],134:[2,173]},{5:128,25:[1,5]},{5:129,25:[1,5]},{1:[2,141],6:[2,141],25:[2,141],26:[2,141],46:[2,141],51:[2,141],54:[2,141],69:[2,141],75:[2,141],83:[2,141],88:[2,141],90:[2,141],99:[2,141],101:[2,141],102:[2,141],103:[2,141],107:[2,141],115:[2,141],123:[2,141],125:[2,141],126:[2,141],129:[2,141],130:[2,141],131:[2,141],132:[2,141],133:[2,141],134:[2,141]},{5:130,25:[1,5]},{8:131,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,132],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,90],5:133,6:[2,90],14:119,15:120,25:[1,5],26:[2,90],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:121,41:60,46:[2,90],51:[2,90],54:[2,90],55:47,56:48,58:135,60:25,61:26,62:27,69:[2,90],73:[1,67],75:[2,90],77:[1,134],80:[1,28],83:[2,90],85:[1,55],86:[1,56],87:[1,54],88:[2,90],90:[2,90],98:[1,53],99:[2,90],101:[2,90],102:[2,90],103:[2,90],107:[2,90],115:[2,90],123:[2,90],125:[2,90],126:[2,90],129:[2,90],130:[2,90],131:[2,90],132:[2,90],133:[2,90],134:[2,90]},{1:[2,43],6:[2,43],8:136,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,26:[2,43],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],99:[2,43],100:39,101:[2,43],103:[2,43],104:40,105:[1,64],106:41,107:[2,43],108:66,116:[1,42],121:37,122:[1,61],123:[2,43],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:137,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,44],6:[2,44],25:[2,44],26:[2,44],51:[2,44],75:[2,44],99:[2,44],101:[2,44],103:[2,44],107:[2,44],123:[2,44]},{1:[2,67],6:[2,67],25:[2,67],26:[2,67],37:[2,67],46:[2,67],51:[2,67],54:[2,67],63:[2,67],64:[2,67],65:[2,67],67:[2,67],69:[2,67],70:[2,67],71:[2,67],75:[2,67],81:[2,67],82:[2,67],83:[2,67],88:[2,67],90:[2,67],99:[2,67],101:[2,67],102:[2,67],103:[2,67],107:[2,67],115:[2,67],123:[2,67],125:[2,67],126:[2,67],129:[2,67],130:[2,67],131:[2,67],132:[2,67],133:[2,67],134:[2,67]},{1:[2,68],6:[2,68],25:[2,68],26:[2,68],37:[2,68],46:[2,68],51:[2,68],54:[2,68],63:[2,68],64:[2,68],65:[2,68],67:[2,68],69:[2,68],70:[2,68],71:[2,68],75:[2,68],81:[2,68],82:[2,68],83:[2,68],88:[2,68],90:[2,68],99:[2,68],101:[2,68],102:[2,68],103:[2,68],107:[2,68],115:[2,68],123:[2,68],125:[2,68],126:[2,68],129:[2,68],130:[2,68],131:[2,68],132:[2,68],133:[2,68],134:[2,68]},{1:[2,29],6:[2,29],25:[2,29],26:[2,29],46:[2,29],51:[2,29],54:[2,29],63:[2,29],64:[2,29],65:[2,29],67:[2,29],69:[2,29],70:[2,29],71:[2,29],75:[2,29],81:[2,29],82:[2,29],83:[2,29],88:[2,29],90:[2,29],99:[2,29],101:[2,29],102:[2,29],103:[2,29],107:[2,29],115:[2,29],123:[2,29],125:[2,29],126:[2,29],129:[2,29],130:[2,29],131:[2,29],132:[2,29],133:[2,29],134:[2,29]},{1:[2,30],6:[2,30],25:[2,30],26:[2,30],46:[2,30],51:[2,30],54:[2,30],63:[2,30],64:[2,30],65:[2,30],67:[2,30],69:[2,30],70:[2,30],71:[2,30],75:[2,30],81:[2,30],82:[2,30],83:[2,30],88:[2,30],90:[2,30],99:[2,30],101:[2,30],102:[2,30],103:[2,30],107:[2,30],115:[2,30],123:[2,30],125:[2,30],126:[2,30],129:[2,30],130:[2,30],131:[2,30],132:[2,30],133:[2,30],134:[2,30]},{1:[2,31],6:[2,31],25:[2,31],26:[2,31],46:[2,31],51:[2,31],54:[2,31],63:[2,31],64:[2,31],65:[2,31],67:[2,31],69:[2,31],70:[2,31],71:[2,31],75:[2,31],81:[2,31],82:[2,31],83:[2,31],88:[2,31],90:[2,31],99:[2,31],101:[2,31],102:[2,31],103:[2,31],107:[2,31],115:[2,31],123:[2,31],125:[2,31],126:[2,31],129:[2,31],130:[2,31],131:[2,31],132:[2,31],133:[2,31],134:[2,31]},{1:[2,32],6:[2,32],25:[2,32],26:[2,32],46:[2,32],51:[2,32],54:[2,32],63:[2,32],64:[2,32],65:[2,32],67:[2,32],69:[2,32],70:[2,32],71:[2,32],75:[2,32],81:[2,32],82:[2,32],83:[2,32],88:[2,32],90:[2,32],99:[2,32],101:[2,32],102:[2,32],103:[2,32],107:[2,32],115:[2,32],123:[2,32],125:[2,32],126:[2,32],129:[2,32],130:[2,32],131:[2,32],132:[2,32],133:[2,32],134:[2,32]},{4:138,7:4,8:6,9:7,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,139],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:140,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,144],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,57:145,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],84:142,85:[1,55],86:[1,56],87:[1,54],88:[1,141],91:143,93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,106],6:[2,106],25:[2,106],26:[2,106],46:[2,106],51:[2,106],54:[2,106],63:[2,106],64:[2,106],65:[2,106],67:[2,106],69:[2,106],70:[2,106],71:[2,106],75:[2,106],81:[2,106],82:[2,106],83:[2,106],88:[2,106],90:[2,106],99:[2,106],101:[2,106],102:[2,106],103:[2,106],107:[2,106],115:[2,106],123:[2,106],125:[2,106],126:[2,106],129:[2,106],130:[2,106],131:[2,106],132:[2,106],133:[2,106],134:[2,106]},{1:[2,107],6:[2,107],25:[2,107],26:[2,107],27:146,28:[1,70],46:[2,107],51:[2,107],54:[2,107],63:[2,107],64:[2,107],65:[2,107],67:[2,107],69:[2,107],70:[2,107],71:[2,107],75:[2,107],81:[2,107],82:[2,107],83:[2,107],88:[2,107],90:[2,107],99:[2,107],101:[2,107],102:[2,107],103:[2,107],107:[2,107],115:[2,107],123:[2,107],125:[2,107],126:[2,107],129:[2,107],130:[2,107],131:[2,107],132:[2,107],133:[2,107],134:[2,107]},{25:[2,47]},{25:[2,48]},{1:[2,62],6:[2,62],25:[2,62],26:[2,62],37:[2,62],46:[2,62],51:[2,62],54:[2,62],63:[2,62],64:[2,62],65:[2,62],67:[2,62],69:[2,62],70:[2,62],71:[2,62],75:[2,62],77:[2,62],81:[2,62],82:[2,62],83:[2,62],88:[2,62],90:[2,62],99:[2,62],101:[2,62],102:[2,62],103:[2,62],107:[2,62],115:[2,62],123:[2,62],125:[2,62],126:[2,62],127:[2,62],128:[2,62],129:[2,62],130:[2,62],131:[2,62],132:[2,62],133:[2,62],134:[2,62],135:[2,62]},{1:[2,65],6:[2,65],25:[2,65],26:[2,65],37:[2,65],46:[2,65],51:[2,65],54:[2,65],63:[2,65],64:[2,65],65:[2,65],67:[2,65],69:[2,65],70:[2,65],71:[2,65],75:[2,65],77:[2,65],81:[2,65],82:[2,65],83:[2,65],88:[2,65],90:[2,65],99:[2,65],101:[2,65],102:[2,65],103:[2,65],107:[2,65],115:[2,65],123:[2,65],125:[2,65],126:[2,65],127:[2,65],128:[2,65],129:[2,65],130:[2,65],131:[2,65],132:[2,65],133:[2,65],134:[2,65],135:[2,65]},{8:147,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:148,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:149,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{5:150,8:151,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,5],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{27:156,28:[1,70],55:157,56:158,61:152,73:[1,67],87:[1,54],110:153,111:[1,154],112:155},{109:159,113:[1,160],114:[1,161]},{6:[2,85],12:165,25:[2,85],27:166,28:[1,70],29:167,30:[1,68],31:[1,69],38:163,39:164,41:168,43:[1,46],51:[2,85],74:162,75:[2,85],86:[1,111]},{1:[2,27],6:[2,27],25:[2,27],26:[2,27],40:[2,27],46:[2,27],51:[2,27],54:[2,27],63:[2,27],64:[2,27],65:[2,27],67:[2,27],69:[2,27],70:[2,27],71:[2,27],75:[2,27],81:[2,27],82:[2,27],83:[2,27],88:[2,27],90:[2,27],99:[2,27],101:[2,27],102:[2,27],103:[2,27],107:[2,27],115:[2,27],123:[2,27],125:[2,27],126:[2,27],129:[2,27],130:[2,27],131:[2,27],132:[2,27],133:[2,27],134:[2,27]},{1:[2,28],6:[2,28],25:[2,28],26:[2,28],40:[2,28],46:[2,28],51:[2,28],54:[2,28],63:[2,28],64:[2,28],65:[2,28],67:[2,28],69:[2,28],70:[2,28],71:[2,28],75:[2,28],81:[2,28],82:[2,28],83:[2,28],88:[2,28],90:[2,28],99:[2,28],101:[2,28],102:[2,28],103:[2,28],107:[2,28],115:[2,28],123:[2,28],125:[2,28],126:[2,28],129:[2,28],130:[2,28],131:[2,28],132:[2,28],133:[2,28],134:[2,28]},{1:[2,26],6:[2,26],25:[2,26],26:[2,26],37:[2,26],40:[2,26],46:[2,26],51:[2,26],54:[2,26],63:[2,26],64:[2,26],65:[2,26],67:[2,26],69:[2,26],70:[2,26],71:[2,26],75:[2,26],77:[2,26],81:[2,26],82:[2,26],83:[2,26],88:[2,26],90:[2,26],99:[2,26],101:[2,26],102:[2,26],103:[2,26],107:[2,26],113:[2,26],114:[2,26],115:[2,26],123:[2,26],125:[2,26],126:[2,26],127:[2,26],128:[2,26],129:[2,26],130:[2,26],131:[2,26],132:[2,26],133:[2,26],134:[2,26],135:[2,26]},{1:[2,6],6:[2,6],7:169,8:6,9:7,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,26:[2,6],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],99:[2,6],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,3]},{1:[2,24],6:[2,24],25:[2,24],26:[2,24],46:[2,24],51:[2,24],54:[2,24],69:[2,24],75:[2,24],83:[2,24],88:[2,24],90:[2,24],95:[2,24],96:[2,24],99:[2,24],101:[2,24],102:[2,24],103:[2,24],107:[2,24],115:[2,24],118:[2,24],120:[2,24],123:[2,24],125:[2,24],126:[2,24],129:[2,24],130:[2,24],131:[2,24],132:[2,24],133:[2,24],134:[2,24]},{6:[1,71],26:[1,170]},{1:[2,184],6:[2,184],25:[2,184],26:[2,184],46:[2,184],51:[2,184],54:[2,184],69:[2,184],75:[2,184],83:[2,184],88:[2,184],90:[2,184],99:[2,184],101:[2,184],102:[2,184],103:[2,184],107:[2,184],115:[2,184],123:[2,184],125:[2,184],126:[2,184],129:[2,184],130:[2,184],131:[2,184],132:[2,184],133:[2,184],134:[2,184]},{8:171,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:172,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:173,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:174,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:175,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:176,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:177,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:178,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,140],6:[2,140],25:[2,140],26:[2,140],46:[2,140],51:[2,140],54:[2,140],69:[2,140],75:[2,140],83:[2,140],88:[2,140],90:[2,140],99:[2,140],101:[2,140],102:[2,140],103:[2,140],107:[2,140],115:[2,140],123:[2,140],125:[2,140],126:[2,140],129:[2,140],130:[2,140],131:[2,140],132:[2,140],133:[2,140],134:[2,140]},{1:[2,145],6:[2,145],25:[2,145],26:[2,145],46:[2,145],51:[2,145],54:[2,145],69:[2,145],75:[2,145],83:[2,145],88:[2,145],90:[2,145],99:[2,145],101:[2,145],102:[2,145],103:[2,145],107:[2,145],115:[2,145],123:[2,145],125:[2,145],126:[2,145],129:[2,145],130:[2,145],131:[2,145],132:[2,145],133:[2,145],134:[2,145]},{8:179,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,139],6:[2,139],25:[2,139],26:[2,139],46:[2,139],51:[2,139],54:[2,139],69:[2,139],75:[2,139],83:[2,139],88:[2,139],90:[2,139],99:[2,139],101:[2,139],102:[2,139],103:[2,139],107:[2,139],115:[2,139],123:[2,139],125:[2,139],126:[2,139],129:[2,139],130:[2,139],131:[2,139],132:[2,139],133:[2,139],134:[2,139]},{1:[2,144],6:[2,144],25:[2,144],26:[2,144],46:[2,144],51:[2,144],54:[2,144],69:[2,144],75:[2,144],83:[2,144],88:[2,144],90:[2,144],99:[2,144],101:[2,144],102:[2,144],103:[2,144],107:[2,144],115:[2,144],123:[2,144],125:[2,144],126:[2,144],129:[2,144],130:[2,144],131:[2,144],132:[2,144],133:[2,144],134:[2,144]},{79:180,82:[1,103]},{1:[2,63],6:[2,63],25:[2,63],26:[2,63],37:[2,63],46:[2,63],51:[2,63],54:[2,63],63:[2,63],64:[2,63],65:[2,63],67:[2,63],69:[2,63],70:[2,63],71:[2,63],75:[2,63],77:[2,63],81:[2,63],82:[2,63],83:[2,63],88:[2,63],90:[2,63],99:[2,63],101:[2,63],102:[2,63],103:[2,63],107:[2,63],115:[2,63],123:[2,63],125:[2,63],126:[2,63],127:[2,63],128:[2,63],129:[2,63],130:[2,63],131:[2,63],132:[2,63],133:[2,63],134:[2,63],135:[2,63]},{82:[2,103]},{27:181,28:[1,70]},{27:182,28:[1,70]},{1:[2,77],6:[2,77],25:[2,77],26:[2,77],27:183,28:[1,70],37:[2,77],46:[2,77],51:[2,77],54:[2,77],63:[2,77],64:[2,77],65:[2,77],67:[2,77],69:[2,77],70:[2,77],71:[2,77],75:[2,77],77:[2,77],81:[2,77],82:[2,77],83:[2,77],88:[2,77],90:[2,77],99:[2,77],101:[2,77],102:[2,77],103:[2,77],107:[2,77],115:[2,77],123:[2,77],125:[2,77],126:[2,77],127:[2,77],128:[2,77],129:[2,77],130:[2,77],131:[2,77],132:[2,77],133:[2,77],134:[2,77],135:[2,77]},{1:[2,78],6:[2,78],25:[2,78],26:[2,78],37:[2,78],46:[2,78],51:[2,78],54:[2,78],63:[2,78],64:[2,78],65:[2,78],67:[2,78],69:[2,78],70:[2,78],71:[2,78],75:[2,78],77:[2,78],81:[2,78],82:[2,78],83:[2,78],88:[2,78],90:[2,78],99:[2,78],101:[2,78],102:[2,78],103:[2,78],107:[2,78],115:[2,78],123:[2,78],125:[2,78],126:[2,78],127:[2,78],128:[2,78],129:[2,78],130:[2,78],131:[2,78],132:[2,78],133:[2,78],134:[2,78],135:[2,78]},{8:185,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],54:[1,189],55:47,56:48,58:36,60:25,61:26,62:27,68:184,72:186,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],89:187,90:[1,188],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{66:190,67:[1,96],70:[1,97],71:[1,98]},{66:191,67:[1,96],70:[1,97],71:[1,98]},{79:192,82:[1,103]},{1:[2,64],6:[2,64],25:[2,64],26:[2,64],37:[2,64],46:[2,64],51:[2,64],54:[2,64],63:[2,64],64:[2,64],65:[2,64],67:[2,64],69:[2,64],70:[2,64],71:[2,64],75:[2,64],77:[2,64],81:[2,64],82:[2,64],83:[2,64],88:[2,64],90:[2,64],99:[2,64],101:[2,64],102:[2,64],103:[2,64],107:[2,64],115:[2,64],123:[2,64],125:[2,64],126:[2,64],127:[2,64],128:[2,64],129:[2,64],130:[2,64],131:[2,64],132:[2,64],133:[2,64],134:[2,64],135:[2,64]},{8:193,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,194],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,101],6:[2,101],25:[2,101],26:[2,101],46:[2,101],51:[2,101],54:[2,101],63:[2,101],64:[2,101],65:[2,101],67:[2,101],69:[2,101],70:[2,101],71:[2,101],75:[2,101],81:[2,101],82:[2,101],83:[2,101],88:[2,101],90:[2,101],99:[2,101],101:[2,101],102:[2,101],103:[2,101],107:[2,101],115:[2,101],123:[2,101],125:[2,101],126:[2,101],129:[2,101],130:[2,101],131:[2,101],132:[2,101],133:[2,101],134:[2,101]},{8:197,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,144],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,57:145,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],83:[1,195],84:196,85:[1,55],86:[1,56],87:[1,54],91:143,93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{46:[1,198],51:[1,199]},{46:[2,52],51:[2,52]},{37:[1,201],46:[2,54],51:[2,54],54:[1,200]},{37:[2,57],46:[2,57],51:[2,57],54:[2,57]},{37:[2,58],46:[2,58],51:[2,58],54:[2,58]},{37:[2,59],46:[2,59],51:[2,59],54:[2,59]},{37:[2,60],46:[2,60],51:[2,60],54:[2,60]},{27:146,28:[1,70]},{8:197,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,144],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,57:145,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],84:142,85:[1,55],86:[1,56],87:[1,54],88:[1,141],91:143,93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,46],6:[2,46],25:[2,46],26:[2,46],46:[2,46],51:[2,46],54:[2,46],69:[2,46],75:[2,46],83:[2,46],88:[2,46],90:[2,46],99:[2,46],101:[2,46],102:[2,46],103:[2,46],107:[2,46],115:[2,46],123:[2,46],125:[2,46],126:[2,46],129:[2,46],130:[2,46],131:[2,46],132:[2,46],133:[2,46],134:[2,46]},{1:[2,177],6:[2,177],25:[2,177],26:[2,177],46:[2,177],51:[2,177],54:[2,177],69:[2,177],75:[2,177],83:[2,177],88:[2,177],90:[2,177],99:[2,177],100:84,101:[2,177],102:[2,177],103:[2,177],106:85,107:[2,177],108:66,115:[2,177],123:[2,177],125:[2,177],126:[2,177],129:[1,75],130:[2,177],131:[2,177],132:[2,177],133:[2,177],134:[2,177]},{100:87,101:[1,62],103:[1,63],106:88,107:[1,65],108:66,123:[1,86]},{1:[2,178],6:[2,178],25:[2,178],26:[2,178],46:[2,178],51:[2,178],54:[2,178],69:[2,178],75:[2,178],83:[2,178],88:[2,178],90:[2,178],99:[2,178],100:84,101:[2,178],102:[2,178],103:[2,178],106:85,107:[2,178],108:66,115:[2,178],123:[2,178],125:[2,178],126:[2,178],129:[1,75],130:[2,178],131:[2,178],132:[2,178],133:[2,178],134:[2,178]},{1:[2,179],6:[2,179],25:[2,179],26:[2,179],46:[2,179],51:[2,179],54:[2,179],69:[2,179],75:[2,179],83:[2,179],88:[2,179],90:[2,179],99:[2,179],100:84,101:[2,179],102:[2,179],103:[2,179],106:85,107:[2,179],108:66,115:[2,179],123:[2,179],125:[2,179],126:[2,179],129:[1,75],130:[2,179],131:[2,179],132:[2,179],133:[2,179],134:[2,179]},{1:[2,180],6:[2,180],25:[2,180],26:[2,180],46:[2,180],51:[2,180],54:[2,180],63:[2,66],64:[2,66],65:[2,66],67:[2,66],69:[2,180],70:[2,66],71:[2,66],75:[2,180],81:[2,66],82:[2,66],83:[2,180],88:[2,180],90:[2,180],99:[2,180],101:[2,180],102:[2,180],103:[2,180],107:[2,180],115:[2,180],123:[2,180],125:[2,180],126:[2,180],129:[2,180],130:[2,180],131:[2,180],132:[2,180],133:[2,180],134:[2,180]},{59:90,63:[1,92],64:[1,93],65:[1,94],66:95,67:[1,96],70:[1,97],71:[1,98],78:89,81:[1,91],82:[2,102]},{59:100,63:[1,92],64:[1,93],65:[1,94],66:95,67:[1,96],70:[1,97],71:[1,98],78:99,81:[1,91],82:[2,102]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],46:[2,69],51:[2,69],54:[2,69],63:[2,69],64:[2,69],65:[2,69],67:[2,69],69:[2,69],70:[2,69],71:[2,69],75:[2,69],81:[2,69],82:[2,69],83:[2,69],88:[2,69],90:[2,69],99:[2,69],101:[2,69],102:[2,69],103:[2,69],107:[2,69],115:[2,69],123:[2,69],125:[2,69],126:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69]},{1:[2,181],6:[2,181],25:[2,181],26:[2,181],46:[2,181],51:[2,181],54:[2,181],63:[2,66],64:[2,66],65:[2,66],67:[2,66],69:[2,181],70:[2,66],71:[2,66],75:[2,181],81:[2,66],82:[2,66],83:[2,181],88:[2,181],90:[2,181],99:[2,181],101:[2,181],102:[2,181],103:[2,181],107:[2,181],115:[2,181],123:[2,181],125:[2,181],126:[2,181],129:[2,181],130:[2,181],131:[2,181],132:[2,181],133:[2,181],134:[2,181]},{1:[2,182],6:[2,182],25:[2,182],26:[2,182],46:[2,182],51:[2,182],54:[2,182],69:[2,182],75:[2,182],83:[2,182],88:[2,182],90:[2,182],99:[2,182],101:[2,182],102:[2,182],103:[2,182],107:[2,182],115:[2,182],123:[2,182],125:[2,182],126:[2,182],129:[2,182],130:[2,182],131:[2,182],132:[2,182],133:[2,182],134:[2,182]},{1:[2,183],6:[2,183],25:[2,183],26:[2,183],46:[2,183],51:[2,183],54:[2,183],69:[2,183],75:[2,183],83:[2,183],88:[2,183],90:[2,183],99:[2,183],101:[2,183],102:[2,183],103:[2,183],107:[2,183],115:[2,183],123:[2,183],125:[2,183],126:[2,183],129:[2,183],130:[2,183],131:[2,183],132:[2,183],133:[2,183],134:[2,183]},{8:202,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,203],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:204,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{5:205,25:[1,5],122:[1,206]},{1:[2,126],6:[2,126],25:[2,126],26:[2,126],46:[2,126],51:[2,126],54:[2,126],69:[2,126],75:[2,126],83:[2,126],88:[2,126],90:[2,126],94:207,95:[1,208],96:[1,209],99:[2,126],101:[2,126],102:[2,126],103:[2,126],107:[2,126],115:[2,126],123:[2,126],125:[2,126],126:[2,126],129:[2,126],130:[2,126],131:[2,126],132:[2,126],133:[2,126],134:[2,126]},{1:[2,138],6:[2,138],25:[2,138],26:[2,138],46:[2,138],51:[2,138],54:[2,138],69:[2,138],75:[2,138],83:[2,138],88:[2,138],90:[2,138],99:[2,138],101:[2,138],102:[2,138],103:[2,138],107:[2,138],115:[2,138],123:[2,138],125:[2,138],126:[2,138],129:[2,138],130:[2,138],131:[2,138],132:[2,138],133:[2,138],134:[2,138]},{1:[2,146],6:[2,146],25:[2,146],26:[2,146],46:[2,146],51:[2,146],54:[2,146],69:[2,146],75:[2,146],83:[2,146],88:[2,146],90:[2,146],99:[2,146],101:[2,146],102:[2,146],103:[2,146],107:[2,146],115:[2,146],123:[2,146],125:[2,146],126:[2,146],129:[2,146],130:[2,146],131:[2,146],132:[2,146],133:[2,146],134:[2,146]},{25:[1,210],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{117:211,119:212,120:[1,213]},{1:[2,91],6:[2,91],25:[2,91],26:[2,91],46:[2,91],51:[2,91],54:[2,91],69:[2,91],75:[2,91],83:[2,91],88:[2,91],90:[2,91],99:[2,91],101:[2,91],102:[2,91],103:[2,91],107:[2,91],115:[2,91],123:[2,91],125:[2,91],126:[2,91],129:[2,91],130:[2,91],131:[2,91],132:[2,91],133:[2,91],134:[2,91]},{14:214,15:120,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:121,41:60,55:47,56:48,58:215,60:25,61:26,62:27,73:[1,67],80:[1,28],85:[1,55],86:[1,56],87:[1,54],98:[1,53]},{1:[2,94],5:216,6:[2,94],25:[1,5],26:[2,94],46:[2,94],51:[2,94],54:[2,94],63:[2,66],64:[2,66],65:[2,66],67:[2,66],69:[2,94],70:[2,66],71:[2,66],75:[2,94],77:[1,217],81:[2,66],82:[2,66],83:[2,94],88:[2,94],90:[2,94],99:[2,94],101:[2,94],102:[2,94],103:[2,94],107:[2,94],115:[2,94],123:[2,94],125:[2,94],126:[2,94],129:[2,94],130:[2,94],131:[2,94],132:[2,94],133:[2,94],134:[2,94]},{1:[2,42],6:[2,42],26:[2,42],99:[2,42],100:84,101:[2,42],103:[2,42],106:85,107:[2,42],108:66,123:[2,42],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,131],6:[2,131],26:[2,131],99:[2,131],100:84,101:[2,131],103:[2,131],106:85,107:[2,131],108:66,123:[2,131],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{6:[1,71],99:[1,218]},{4:219,7:4,8:6,9:7,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,122],25:[2,122],51:[2,122],54:[1,221],88:[2,122],89:220,90:[1,188],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,109],6:[2,109],25:[2,109],26:[2,109],37:[2,109],46:[2,109],51:[2,109],54:[2,109],63:[2,109],64:[2,109],65:[2,109],67:[2,109],69:[2,109],70:[2,109],71:[2,109],75:[2,109],81:[2,109],82:[2,109],83:[2,109],88:[2,109],90:[2,109],99:[2,109],101:[2,109],102:[2,109],103:[2,109],107:[2,109],113:[2,109],114:[2,109],115:[2,109],123:[2,109],125:[2,109],126:[2,109],129:[2,109],130:[2,109],131:[2,109],132:[2,109],133:[2,109],134:[2,109]},{6:[2,49],25:[2,49],50:222,51:[1,223],88:[2,49]},{6:[2,117],25:[2,117],26:[2,117],51:[2,117],83:[2,117],88:[2,117]},{8:197,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,144],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,57:145,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],84:224,85:[1,55],86:[1,56],87:[1,54],91:143,93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,123],25:[2,123],26:[2,123],51:[2,123],83:[2,123],88:[2,123]},{1:[2,108],6:[2,108],25:[2,108],26:[2,108],37:[2,108],40:[2,108],46:[2,108],51:[2,108],54:[2,108],63:[2,108],64:[2,108],65:[2,108],67:[2,108],69:[2,108],70:[2,108],71:[2,108],75:[2,108],77:[2,108],81:[2,108],82:[2,108],83:[2,108],88:[2,108],90:[2,108],99:[2,108],101:[2,108],102:[2,108],103:[2,108],107:[2,108],115:[2,108],123:[2,108],125:[2,108],126:[2,108],127:[2,108],128:[2,108],129:[2,108],130:[2,108],131:[2,108],132:[2,108],133:[2,108],134:[2,108],135:[2,108]},{5:225,25:[1,5],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,134],6:[2,134],25:[2,134],26:[2,134],46:[2,134],51:[2,134],54:[2,134],69:[2,134],75:[2,134],83:[2,134],88:[2,134],90:[2,134],99:[2,134],100:84,101:[1,62],102:[1,226],103:[1,63],106:85,107:[1,65],108:66,115:[2,134],123:[2,134],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,136],6:[2,136],25:[2,136],26:[2,136],46:[2,136],51:[2,136],54:[2,136],69:[2,136],75:[2,136],83:[2,136],88:[2,136],90:[2,136],99:[2,136],100:84,101:[1,62],102:[1,227],103:[1,63],106:85,107:[1,65],108:66,115:[2,136],123:[2,136],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,142],6:[2,142],25:[2,142],26:[2,142],46:[2,142],51:[2,142],54:[2,142],69:[2,142],75:[2,142],83:[2,142],88:[2,142],90:[2,142],99:[2,142],101:[2,142],102:[2,142],103:[2,142],107:[2,142],115:[2,142],123:[2,142],125:[2,142],126:[2,142],129:[2,142],130:[2,142],131:[2,142],132:[2,142],133:[2,142],134:[2,142]},{1:[2,143],6:[2,143],25:[2,143],26:[2,143],46:[2,143],51:[2,143],54:[2,143],69:[2,143],75:[2,143],83:[2,143],88:[2,143],90:[2,143],99:[2,143],100:84,101:[1,62],102:[2,143],103:[1,63],106:85,107:[1,65],108:66,115:[2,143],123:[2,143],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,147],6:[2,147],25:[2,147],26:[2,147],46:[2,147],51:[2,147],54:[2,147],69:[2,147],75:[2,147],83:[2,147],88:[2,147],90:[2,147],99:[2,147],101:[2,147],102:[2,147],103:[2,147],107:[2,147],115:[2,147],123:[2,147],125:[2,147],126:[2,147],129:[2,147],130:[2,147],131:[2,147],132:[2,147],133:[2,147],134:[2,147]},{113:[2,149],114:[2,149]},{27:156,28:[1,70],55:157,56:158,73:[1,67],87:[1,112],110:228,112:155},{51:[1,229],113:[2,154],114:[2,154]},{51:[2,151],113:[2,151],114:[2,151]},{51:[2,152],113:[2,152],114:[2,152]},{51:[2,153],113:[2,153],114:[2,153]},{1:[2,148],6:[2,148],25:[2,148],26:[2,148],46:[2,148],51:[2,148],54:[2,148],69:[2,148],75:[2,148],83:[2,148],88:[2,148],90:[2,148],99:[2,148],101:[2,148],102:[2,148],103:[2,148],107:[2,148],115:[2,148],123:[2,148],125:[2,148],126:[2,148],129:[2,148],130:[2,148],131:[2,148],132:[2,148],133:[2,148],134:[2,148]},{8:230,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:231,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,49],25:[2,49],50:232,51:[1,233],75:[2,49]},{6:[2,86],25:[2,86],26:[2,86],51:[2,86],75:[2,86]},{6:[2,35],25:[2,35],26:[2,35],40:[1,234],51:[2,35],75:[2,35]},{6:[2,38],25:[2,38],26:[2,38],51:[2,38],75:[2,38]},{6:[2,39],25:[2,39],26:[2,39],40:[2,39],51:[2,39],75:[2,39]},{6:[2,40],25:[2,40],26:[2,40],40:[2,40],51:[2,40],75:[2,40]},{6:[2,41],25:[2,41],26:[2,41],40:[2,41],51:[2,41],75:[2,41]},{1:[2,5],6:[2,5],26:[2,5],99:[2,5]},{1:[2,25],6:[2,25],25:[2,25],26:[2,25],46:[2,25],51:[2,25],54:[2,25],69:[2,25],75:[2,25],83:[2,25],88:[2,25],90:[2,25],95:[2,25],96:[2,25],99:[2,25],101:[2,25],102:[2,25],103:[2,25],107:[2,25],115:[2,25],118:[2,25],120:[2,25],123:[2,25],125:[2,25],126:[2,25],129:[2,25],130:[2,25],131:[2,25],132:[2,25],133:[2,25],134:[2,25]},{1:[2,185],6:[2,185],25:[2,185],26:[2,185],46:[2,185],51:[2,185],54:[2,185],69:[2,185],75:[2,185],83:[2,185],88:[2,185],90:[2,185],99:[2,185],100:84,101:[2,185],102:[2,185],103:[2,185],106:85,107:[2,185],108:66,115:[2,185],123:[2,185],125:[2,185],126:[2,185],129:[1,75],130:[1,78],131:[2,185],132:[2,185],133:[2,185],134:[2,185]},{1:[2,186],6:[2,186],25:[2,186],26:[2,186],46:[2,186],51:[2,186],54:[2,186],69:[2,186],75:[2,186],83:[2,186],88:[2,186],90:[2,186],99:[2,186],100:84,101:[2,186],102:[2,186],103:[2,186],106:85,107:[2,186],108:66,115:[2,186],123:[2,186],125:[2,186],126:[2,186],129:[1,75],130:[1,78],131:[2,186],132:[2,186],133:[2,186],134:[2,186]},{1:[2,187],6:[2,187],25:[2,187],26:[2,187],46:[2,187],51:[2,187],54:[2,187],69:[2,187],75:[2,187],83:[2,187],88:[2,187],90:[2,187],99:[2,187],100:84,101:[2,187],102:[2,187],103:[2,187],106:85,107:[2,187],108:66,115:[2,187],123:[2,187],125:[2,187],126:[2,187],129:[1,75],130:[2,187],131:[2,187],132:[2,187],133:[2,187],134:[2,187]},{1:[2,188],6:[2,188],25:[2,188],26:[2,188],46:[2,188],51:[2,188],54:[2,188],69:[2,188],75:[2,188],83:[2,188],88:[2,188],90:[2,188],99:[2,188],100:84,101:[2,188],102:[2,188],103:[2,188],106:85,107:[2,188],108:66,115:[2,188],123:[2,188],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[2,188],132:[2,188],133:[2,188],134:[2,188]},{1:[2,189],6:[2,189],25:[2,189],26:[2,189],46:[2,189],51:[2,189],54:[2,189],69:[2,189],75:[2,189],83:[2,189],88:[2,189],90:[2,189],99:[2,189],100:84,101:[2,189],102:[2,189],103:[2,189],106:85,107:[2,189],108:66,115:[2,189],123:[2,189],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[2,189],133:[2,189],134:[1,82]},{1:[2,190],6:[2,190],25:[2,190],26:[2,190],46:[2,190],51:[2,190],54:[2,190],69:[2,190],75:[2,190],83:[2,190],88:[2,190],90:[2,190],99:[2,190],100:84,101:[2,190],102:[2,190],103:[2,190],106:85,107:[2,190],108:66,115:[2,190],123:[2,190],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[2,190],134:[1,82]},{1:[2,191],6:[2,191],25:[2,191],26:[2,191],46:[2,191],51:[2,191],54:[2,191],69:[2,191],75:[2,191],83:[2,191],88:[2,191],90:[2,191],99:[2,191],100:84,101:[2,191],102:[2,191],103:[2,191],106:85,107:[2,191],108:66,115:[2,191],123:[2,191],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[2,191],133:[2,191],134:[2,191]},{1:[2,176],6:[2,176],25:[2,176],26:[2,176],46:[2,176],51:[2,176],54:[2,176],69:[2,176],75:[2,176],83:[2,176],88:[2,176],90:[2,176],99:[2,176],100:84,101:[1,62],102:[2,176],103:[1,63],106:85,107:[1,65],108:66,115:[2,176],123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,175],6:[2,175],25:[2,175],26:[2,175],46:[2,175],51:[2,175],54:[2,175],69:[2,175],75:[2,175],83:[2,175],88:[2,175],90:[2,175],99:[2,175],100:84,101:[1,62],102:[2,175],103:[1,63],106:85,107:[1,65],108:66,115:[2,175],123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,98],6:[2,98],25:[2,98],26:[2,98],46:[2,98],51:[2,98],54:[2,98],63:[2,98],64:[2,98],65:[2,98],67:[2,98],69:[2,98],70:[2,98],71:[2,98],75:[2,98],81:[2,98],82:[2,98],83:[2,98],88:[2,98],90:[2,98],99:[2,98],101:[2,98],102:[2,98],103:[2,98],107:[2,98],115:[2,98],123:[2,98],125:[2,98],126:[2,98],129:[2,98],130:[2,98],131:[2,98],132:[2,98],133:[2,98],134:[2,98]},{1:[2,74],6:[2,74],25:[2,74],26:[2,74],37:[2,74],46:[2,74],51:[2,74],54:[2,74],63:[2,74],64:[2,74],65:[2,74],67:[2,74],69:[2,74],70:[2,74],71:[2,74],75:[2,74],77:[2,74],81:[2,74],82:[2,74],83:[2,74],88:[2,74],90:[2,74],99:[2,74],101:[2,74],102:[2,74],103:[2,74],107:[2,74],115:[2,74],123:[2,74],125:[2,74],126:[2,74],127:[2,74],128:[2,74],129:[2,74],130:[2,74],131:[2,74],132:[2,74],133:[2,74],134:[2,74],135:[2,74]},{1:[2,75],6:[2,75],25:[2,75],26:[2,75],37:[2,75],46:[2,75],51:[2,75],54:[2,75],63:[2,75],64:[2,75],65:[2,75],67:[2,75],69:[2,75],70:[2,75],71:[2,75],75:[2,75],77:[2,75],81:[2,75],82:[2,75],83:[2,75],88:[2,75],90:[2,75],99:[2,75],101:[2,75],102:[2,75],103:[2,75],107:[2,75],115:[2,75],123:[2,75],125:[2,75],126:[2,75],127:[2,75],128:[2,75],129:[2,75],130:[2,75],131:[2,75],132:[2,75],133:[2,75],134:[2,75],135:[2,75]},{1:[2,76],6:[2,76],25:[2,76],26:[2,76],37:[2,76],46:[2,76],51:[2,76],54:[2,76],63:[2,76],64:[2,76],65:[2,76],67:[2,76],69:[2,76],70:[2,76],71:[2,76],75:[2,76],77:[2,76],81:[2,76],82:[2,76],83:[2,76],88:[2,76],90:[2,76],99:[2,76],101:[2,76],102:[2,76],103:[2,76],107:[2,76],115:[2,76],123:[2,76],125:[2,76],126:[2,76],127:[2,76],128:[2,76],129:[2,76],130:[2,76],131:[2,76],132:[2,76],133:[2,76],134:[2,76],135:[2,76]},{69:[1,235]},{54:[1,189],69:[2,82],89:236,90:[1,188],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{69:[2,83]},{8:237,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{13:[2,111],28:[2,111],30:[2,111],31:[2,111],33:[2,111],34:[2,111],35:[2,111],42:[2,111],43:[2,111],44:[2,111],48:[2,111],49:[2,111],69:[2,111],73:[2,111],76:[2,111],80:[2,111],85:[2,111],86:[2,111],87:[2,111],93:[2,111],97:[2,111],98:[2,111],101:[2,111],103:[2,111],105:[2,111],107:[2,111],116:[2,111],122:[2,111],124:[2,111],125:[2,111],126:[2,111],127:[2,111],128:[2,111]},{13:[2,112],28:[2,112],30:[2,112],31:[2,112],33:[2,112],34:[2,112],35:[2,112],42:[2,112],43:[2,112],44:[2,112],48:[2,112],49:[2,112],69:[2,112],73:[2,112],76:[2,112],80:[2,112],85:[2,112],86:[2,112],87:[2,112],93:[2,112],97:[2,112],98:[2,112],101:[2,112],103:[2,112],105:[2,112],107:[2,112],116:[2,112],122:[2,112],124:[2,112],125:[2,112],126:[2,112],127:[2,112],128:[2,112]},{1:[2,80],6:[2,80],25:[2,80],26:[2,80],37:[2,80],46:[2,80],51:[2,80],54:[2,80],63:[2,80],64:[2,80],65:[2,80],67:[2,80],69:[2,80],70:[2,80],71:[2,80],75:[2,80],77:[2,80],81:[2,80],82:[2,80],83:[2,80],88:[2,80],90:[2,80],99:[2,80],101:[2,80],102:[2,80],103:[2,80],107:[2,80],115:[2,80],123:[2,80],125:[2,80],126:[2,80],127:[2,80],128:[2,80],129:[2,80],130:[2,80],131:[2,80],132:[2,80],133:[2,80],134:[2,80],135:[2,80]},{1:[2,81],6:[2,81],25:[2,81],26:[2,81],37:[2,81],46:[2,81],51:[2,81],54:[2,81],63:[2,81],64:[2,81],65:[2,81],67:[2,81],69:[2,81],70:[2,81],71:[2,81],75:[2,81],77:[2,81],81:[2,81],82:[2,81],83:[2,81],88:[2,81],90:[2,81],99:[2,81],101:[2,81],102:[2,81],103:[2,81],107:[2,81],115:[2,81],123:[2,81],125:[2,81],126:[2,81],127:[2,81],128:[2,81],129:[2,81],130:[2,81],131:[2,81],132:[2,81],133:[2,81],134:[2,81],135:[2,81]},{1:[2,99],6:[2,99],25:[2,99],26:[2,99],46:[2,99],51:[2,99],54:[2,99],63:[2,99],64:[2,99],65:[2,99],67:[2,99],69:[2,99],70:[2,99],71:[2,99],75:[2,99],81:[2,99],82:[2,99],83:[2,99],88:[2,99],90:[2,99],99:[2,99],101:[2,99],102:[2,99],103:[2,99],107:[2,99],115:[2,99],123:[2,99],125:[2,99],126:[2,99],129:[2,99],130:[2,99],131:[2,99],132:[2,99],133:[2,99],134:[2,99]},{1:[2,33],6:[2,33],25:[2,33],26:[2,33],46:[2,33],51:[2,33],54:[2,33],69:[2,33],75:[2,33],83:[2,33],88:[2,33],90:[2,33],99:[2,33],100:84,101:[2,33],102:[2,33],103:[2,33],106:85,107:[2,33],108:66,115:[2,33],123:[2,33],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{8:238,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,104],6:[2,104],25:[2,104],26:[2,104],46:[2,104],51:[2,104],54:[2,104],63:[2,104],64:[2,104],65:[2,104],67:[2,104],69:[2,104],70:[2,104],71:[2,104],75:[2,104],81:[2,104],82:[2,104],83:[2,104],88:[2,104],90:[2,104],99:[2,104],101:[2,104],102:[2,104],103:[2,104],107:[2,104],115:[2,104],123:[2,104],125:[2,104],126:[2,104],129:[2,104],130:[2,104],131:[2,104],132:[2,104],133:[2,104],134:[2,104]},{6:[2,49],25:[2,49],50:239,51:[1,223],83:[2,49]},{6:[2,122],25:[2,122],26:[2,122],51:[2,122],54:[1,240],83:[2,122],88:[2,122],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{47:241,48:[1,57],49:[1,58]},{27:107,28:[1,70],41:108,52:242,53:106,55:109,56:110,73:[1,67],86:[1,111],87:[1,112]},{46:[2,55],51:[2,55]},{8:243,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,192],6:[2,192],25:[2,192],26:[2,192],46:[2,192],51:[2,192],54:[2,192],69:[2,192],75:[2,192],83:[2,192],88:[2,192],90:[2,192],99:[2,192],100:84,101:[2,192],102:[2,192],103:[2,192],106:85,107:[2,192],108:66,115:[2,192],123:[2,192],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{8:244,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,194],6:[2,194],25:[2,194],26:[2,194],46:[2,194],51:[2,194],54:[2,194],69:[2,194],75:[2,194],83:[2,194],88:[2,194],90:[2,194],99:[2,194],100:84,101:[2,194],102:[2,194],103:[2,194],106:85,107:[2,194],108:66,115:[2,194],123:[2,194],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,174],6:[2,174],25:[2,174],26:[2,174],46:[2,174],51:[2,174],54:[2,174],69:[2,174],75:[2,174],83:[2,174],88:[2,174],90:[2,174],99:[2,174],101:[2,174],102:[2,174],103:[2,174],107:[2,174],115:[2,174],123:[2,174],125:[2,174],126:[2,174],129:[2,174],130:[2,174],131:[2,174],132:[2,174],133:[2,174],134:[2,174]},{8:245,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,127],6:[2,127],25:[2,127],26:[2,127],46:[2,127],51:[2,127],54:[2,127],69:[2,127],75:[2,127],83:[2,127],88:[2,127],90:[2,127],95:[1,246],99:[2,127],101:[2,127],102:[2,127],103:[2,127],107:[2,127],115:[2,127],123:[2,127],125:[2,127],126:[2,127],129:[2,127],130:[2,127],131:[2,127],132:[2,127],133:[2,127],134:[2,127]},{5:247,25:[1,5]},{27:248,28:[1,70]},{117:249,119:212,120:[1,213]},{26:[1,250],118:[1,251],119:252,120:[1,213]},{26:[2,167],118:[2,167],120:[2,167]},{8:254,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],92:253,93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,92],5:255,6:[2,92],25:[1,5],26:[2,92],46:[2,92],51:[2,92],54:[2,92],59:90,63:[1,92],64:[1,93],65:[1,94],66:95,67:[1,96],69:[2,92],70:[1,97],71:[1,98],75:[2,92],78:89,81:[1,91],82:[2,102],83:[2,92],88:[2,92],90:[2,92],99:[2,92],101:[2,92],102:[2,92],103:[2,92],107:[2,92],115:[2,92],123:[2,92],125:[2,92],126:[2,92],129:[2,92],130:[2,92],131:[2,92],132:[2,92],133:[2,92],134:[2,92]},{1:[2,66],6:[2,66],25:[2,66],26:[2,66],46:[2,66],51:[2,66],54:[2,66],63:[2,66],64:[2,66],65:[2,66],67:[2,66],69:[2,66],70:[2,66],71:[2,66],75:[2,66],81:[2,66],82:[2,66],83:[2,66],88:[2,66],90:[2,66],99:[2,66],101:[2,66],102:[2,66],103:[2,66],107:[2,66],115:[2,66],123:[2,66],125:[2,66],126:[2,66],129:[2,66],130:[2,66],131:[2,66],132:[2,66],133:[2,66],134:[2,66]},{1:[2,95],6:[2,95],25:[2,95],26:[2,95],46:[2,95],51:[2,95],54:[2,95],69:[2,95],75:[2,95],83:[2,95],88:[2,95],90:[2,95],99:[2,95],101:[2,95],102:[2,95],103:[2,95],107:[2,95],115:[2,95],123:[2,95],125:[2,95],126:[2,95],129:[2,95],130:[2,95],131:[2,95],132:[2,95],133:[2,95],134:[2,95]},{14:256,15:120,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:121,41:60,55:47,56:48,58:215,60:25,61:26,62:27,73:[1,67],80:[1,28],85:[1,55],86:[1,56],87:[1,54],98:[1,53]},{1:[2,132],6:[2,132],25:[2,132],26:[2,132],46:[2,132],51:[2,132],54:[2,132],63:[2,132],64:[2,132],65:[2,132],67:[2,132],69:[2,132],70:[2,132],71:[2,132],75:[2,132],81:[2,132],82:[2,132],83:[2,132],88:[2,132],90:[2,132],99:[2,132],101:[2,132],102:[2,132],103:[2,132],107:[2,132],115:[2,132],123:[2,132],125:[2,132],126:[2,132],129:[2,132],130:[2,132],131:[2,132],132:[2,132],133:[2,132],134:[2,132]},{6:[1,71],26:[1,257]},{8:258,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,61],13:[2,112],25:[2,61],28:[2,112],30:[2,112],31:[2,112],33:[2,112],34:[2,112],35:[2,112],42:[2,112],43:[2,112],44:[2,112],48:[2,112],49:[2,112],51:[2,61],73:[2,112],76:[2,112],80:[2,112],85:[2,112],86:[2,112],87:[2,112],88:[2,61],93:[2,112],97:[2,112],98:[2,112],101:[2,112],103:[2,112],105:[2,112],107:[2,112],116:[2,112],122:[2,112],124:[2,112],125:[2,112],126:[2,112],127:[2,112],128:[2,112]},{6:[1,260],25:[1,261],88:[1,259]},{6:[2,50],8:197,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[2,50],26:[2,50],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,57:145,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],83:[2,50],85:[1,55],86:[1,56],87:[1,54],88:[2,50],91:262,93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,49],25:[2,49],26:[2,49],50:263,51:[1,223]},{1:[2,171],6:[2,171],25:[2,171],26:[2,171],46:[2,171],51:[2,171],54:[2,171],69:[2,171],75:[2,171],83:[2,171],88:[2,171],90:[2,171],99:[2,171],101:[2,171],102:[2,171],103:[2,171],107:[2,171],115:[2,171],118:[2,171],123:[2,171],125:[2,171],126:[2,171],129:[2,171],130:[2,171],131:[2,171],132:[2,171],133:[2,171],134:[2,171]},{8:264,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:265,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{113:[2,150],114:[2,150]},{27:156,28:[1,70],55:157,56:158,73:[1,67],87:[1,112],112:266},{1:[2,156],6:[2,156],25:[2,156],26:[2,156],46:[2,156],51:[2,156],54:[2,156],69:[2,156],75:[2,156],83:[2,156],88:[2,156],90:[2,156],99:[2,156],100:84,101:[2,156],102:[1,267],103:[2,156],106:85,107:[2,156],108:66,115:[1,268],123:[2,156],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,157],6:[2,157],25:[2,157],26:[2,157],46:[2,157],51:[2,157],54:[2,157],69:[2,157],75:[2,157],83:[2,157],88:[2,157],90:[2,157],99:[2,157],100:84,101:[2,157],102:[1,269],103:[2,157],106:85,107:[2,157],108:66,115:[2,157],123:[2,157],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{6:[1,271],25:[1,272],75:[1,270]},{6:[2,50],12:165,25:[2,50],26:[2,50],27:166,28:[1,70],29:167,30:[1,68],31:[1,69],38:273,39:164,41:168,43:[1,46],75:[2,50],86:[1,111]},{8:274,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,275],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,79],6:[2,79],25:[2,79],26:[2,79],37:[2,79],46:[2,79],51:[2,79],54:[2,79],63:[2,79],64:[2,79],65:[2,79],67:[2,79],69:[2,79],70:[2,79],71:[2,79],75:[2,79],77:[2,79],81:[2,79],82:[2,79],83:[2,79],88:[2,79],90:[2,79],99:[2,79],101:[2,79],102:[2,79],103:[2,79],107:[2,79],115:[2,79],123:[2,79],125:[2,79],126:[2,79],127:[2,79],128:[2,79],129:[2,79],130:[2,79],131:[2,79],132:[2,79],133:[2,79],134:[2,79],135:[2,79]},{8:276,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,69:[2,115],73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{69:[2,116],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{26:[1,277],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{6:[1,260],25:[1,261],83:[1,278]},{6:[2,61],25:[2,61],26:[2,61],51:[2,61],83:[2,61],88:[2,61]},{5:279,25:[1,5]},{46:[2,53],51:[2,53]},{46:[2,56],51:[2,56],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{26:[1,280],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{5:281,25:[1,5],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{5:282,25:[1,5]},{1:[2,128],6:[2,128],25:[2,128],26:[2,128],46:[2,128],51:[2,128],54:[2,128],69:[2,128],75:[2,128],83:[2,128],88:[2,128],90:[2,128],99:[2,128],101:[2,128],102:[2,128],103:[2,128],107:[2,128],115:[2,128],123:[2,128],125:[2,128],126:[2,128],129:[2,128],130:[2,128],131:[2,128],132:[2,128],133:[2,128],134:[2,128]},{5:283,25:[1,5]},{26:[1,284],118:[1,285],119:252,120:[1,213]},{1:[2,165],6:[2,165],25:[2,165],26:[2,165],46:[2,165],51:[2,165],54:[2,165],69:[2,165],75:[2,165],83:[2,165],88:[2,165],90:[2,165],99:[2,165],101:[2,165],102:[2,165],103:[2,165],107:[2,165],115:[2,165],123:[2,165],125:[2,165],126:[2,165],129:[2,165],130:[2,165],131:[2,165],132:[2,165],133:[2,165],134:[2,165]},{5:286,25:[1,5]},{26:[2,168],118:[2,168],120:[2,168]},{5:287,25:[1,5],51:[1,288]},{25:[2,124],51:[2,124],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,93],6:[2,93],25:[2,93],26:[2,93],46:[2,93],51:[2,93],54:[2,93],69:[2,93],75:[2,93],83:[2,93],88:[2,93],90:[2,93],99:[2,93],101:[2,93],102:[2,93],103:[2,93],107:[2,93],115:[2,93],123:[2,93],125:[2,93],126:[2,93],129:[2,93],130:[2,93],131:[2,93],132:[2,93],133:[2,93],134:[2,93]},{1:[2,96],5:289,6:[2,96],25:[1,5],26:[2,96],46:[2,96],51:[2,96],54:[2,96],59:90,63:[1,92],64:[1,93],65:[1,94],66:95,67:[1,96],69:[2,96],70:[1,97],71:[1,98],75:[2,96],78:89,81:[1,91],82:[2,102],83:[2,96],88:[2,96],90:[2,96],99:[2,96],101:[2,96],102:[2,96],103:[2,96],107:[2,96],115:[2,96],123:[2,96],125:[2,96],126:[2,96],129:[2,96],130:[2,96],131:[2,96],132:[2,96],133:[2,96],134:[2,96]},{99:[1,290]},{88:[1,291],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,110],6:[2,110],25:[2,110],26:[2,110],37:[2,110],46:[2,110],51:[2,110],54:[2,110],63:[2,110],64:[2,110],65:[2,110],67:[2,110],69:[2,110],70:[2,110],71:[2,110],75:[2,110],81:[2,110],82:[2,110],83:[2,110],88:[2,110],90:[2,110],99:[2,110],101:[2,110],102:[2,110],103:[2,110],107:[2,110],113:[2,110],114:[2,110],115:[2,110],123:[2,110],125:[2,110],126:[2,110],129:[2,110],130:[2,110],131:[2,110],132:[2,110],133:[2,110],134:[2,110]},{8:197,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,57:145,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],91:292,93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:197,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,25:[1,144],27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,57:145,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],84:293,85:[1,55],86:[1,56],87:[1,54],91:143,93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,118],25:[2,118],26:[2,118],51:[2,118],83:[2,118],88:[2,118]},{6:[1,260],25:[1,261],26:[1,294]},{1:[2,135],6:[2,135],25:[2,135],26:[2,135],46:[2,135],51:[2,135],54:[2,135],69:[2,135],75:[2,135],83:[2,135],88:[2,135],90:[2,135],99:[2,135],100:84,101:[1,62],102:[2,135],103:[1,63],106:85,107:[1,65],108:66,115:[2,135],123:[2,135],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,137],6:[2,137],25:[2,137],26:[2,137],46:[2,137],51:[2,137],54:[2,137],69:[2,137],75:[2,137],83:[2,137],88:[2,137],90:[2,137],99:[2,137],100:84,101:[1,62],102:[2,137],103:[1,63],106:85,107:[1,65],108:66,115:[2,137],123:[2,137],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{113:[2,155],114:[2,155]},{8:295,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:296,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:297,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,84],6:[2,84],25:[2,84],26:[2,84],37:[2,84],46:[2,84],51:[2,84],54:[2,84],63:[2,84],64:[2,84],65:[2,84],67:[2,84],69:[2,84],70:[2,84],71:[2,84],75:[2,84],81:[2,84],82:[2,84],83:[2,84],88:[2,84],90:[2,84],99:[2,84],101:[2,84],102:[2,84],103:[2,84],107:[2,84],113:[2,84],114:[2,84],115:[2,84],123:[2,84],125:[2,84],126:[2,84],129:[2,84],130:[2,84],131:[2,84],132:[2,84],133:[2,84],134:[2,84]},{12:165,27:166,28:[1,70],29:167,30:[1,68],31:[1,69],38:298,39:164,41:168,43:[1,46],86:[1,111]},{6:[2,85],12:165,25:[2,85],26:[2,85],27:166,28:[1,70],29:167,30:[1,68],31:[1,69],38:163,39:164,41:168,43:[1,46],51:[2,85],74:299,86:[1,111]},{6:[2,87],25:[2,87],26:[2,87],51:[2,87],75:[2,87]},{6:[2,36],25:[2,36],26:[2,36],51:[2,36],75:[2,36],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{8:300,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{69:[2,114],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,34],6:[2,34],25:[2,34],26:[2,34],46:[2,34],51:[2,34],54:[2,34],69:[2,34],75:[2,34],83:[2,34],88:[2,34],90:[2,34],99:[2,34],101:[2,34],102:[2,34],103:[2,34],107:[2,34],115:[2,34],123:[2,34],125:[2,34],126:[2,34],129:[2,34],130:[2,34],131:[2,34],132:[2,34],133:[2,34],134:[2,34]},{1:[2,105],6:[2,105],25:[2,105],26:[2,105],46:[2,105],51:[2,105],54:[2,105],63:[2,105],64:[2,105],65:[2,105],67:[2,105],69:[2,105],70:[2,105],71:[2,105],75:[2,105],81:[2,105],82:[2,105],83:[2,105],88:[2,105],90:[2,105],99:[2,105],101:[2,105],102:[2,105],103:[2,105],107:[2,105],115:[2,105],123:[2,105],125:[2,105],126:[2,105],129:[2,105],130:[2,105],131:[2,105],132:[2,105],133:[2,105],134:[2,105]},{1:[2,45],6:[2,45],25:[2,45],26:[2,45],46:[2,45],51:[2,45],54:[2,45],69:[2,45],75:[2,45],83:[2,45],88:[2,45],90:[2,45],99:[2,45],101:[2,45],102:[2,45],103:[2,45],107:[2,45],115:[2,45],123:[2,45],125:[2,45],126:[2,45],129:[2,45],130:[2,45],131:[2,45],132:[2,45],133:[2,45],134:[2,45]},{1:[2,193],6:[2,193],25:[2,193],26:[2,193],46:[2,193],51:[2,193],54:[2,193],69:[2,193],75:[2,193],83:[2,193],88:[2,193],90:[2,193],99:[2,193],101:[2,193],102:[2,193],103:[2,193],107:[2,193],115:[2,193],123:[2,193],125:[2,193],126:[2,193],129:[2,193],130:[2,193],131:[2,193],132:[2,193],133:[2,193],134:[2,193]},{1:[2,172],6:[2,172],25:[2,172],26:[2,172],46:[2,172],51:[2,172],54:[2,172],69:[2,172],75:[2,172],83:[2,172],88:[2,172],90:[2,172],99:[2,172],101:[2,172],102:[2,172],103:[2,172],107:[2,172],115:[2,172],118:[2,172],123:[2,172],125:[2,172],126:[2,172],129:[2,172],130:[2,172],131:[2,172],132:[2,172],133:[2,172],134:[2,172]},{1:[2,129],6:[2,129],25:[2,129],26:[2,129],46:[2,129],51:[2,129],54:[2,129],69:[2,129],75:[2,129],83:[2,129],88:[2,129],90:[2,129],99:[2,129],101:[2,129],102:[2,129],103:[2,129],107:[2,129],115:[2,129],123:[2,129],125:[2,129],126:[2,129],129:[2,129],130:[2,129],131:[2,129],132:[2,129],133:[2,129],134:[2,129]},{1:[2,130],6:[2,130],25:[2,130],26:[2,130],46:[2,130],51:[2,130],54:[2,130],69:[2,130],75:[2,130],83:[2,130],88:[2,130],90:[2,130],95:[2,130],99:[2,130],101:[2,130],102:[2,130],103:[2,130],107:[2,130],115:[2,130],123:[2,130],125:[2,130],126:[2,130],129:[2,130],130:[2,130],131:[2,130],132:[2,130],133:[2,130],134:[2,130]},{1:[2,163],6:[2,163],25:[2,163],26:[2,163],46:[2,163],51:[2,163],54:[2,163],69:[2,163],75:[2,163],83:[2,163],88:[2,163],90:[2,163],99:[2,163],101:[2,163],102:[2,163],103:[2,163],107:[2,163],115:[2,163],123:[2,163],125:[2,163],126:[2,163],129:[2,163],130:[2,163],131:[2,163],132:[2,163],133:[2,163],134:[2,163]},{5:301,25:[1,5]},{26:[1,302]},{6:[1,303],26:[2,169],118:[2,169],120:[2,169]},{8:304,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,97],6:[2,97],25:[2,97],26:[2,97],46:[2,97],51:[2,97],54:[2,97],69:[2,97],75:[2,97],83:[2,97],88:[2,97],90:[2,97],99:[2,97],101:[2,97],102:[2,97],103:[2,97],107:[2,97],115:[2,97],123:[2,97],125:[2,97],126:[2,97],129:[2,97],130:[2,97],131:[2,97],132:[2,97],133:[2,97],134:[2,97]},{1:[2,133],6:[2,133],25:[2,133],26:[2,133],46:[2,133],51:[2,133],54:[2,133],63:[2,133],64:[2,133],65:[2,133],67:[2,133],69:[2,133],70:[2,133],71:[2,133],75:[2,133],81:[2,133],82:[2,133],83:[2,133],88:[2,133],90:[2,133],99:[2,133],101:[2,133],102:[2,133],103:[2,133],107:[2,133],115:[2,133],123:[2,133],125:[2,133],126:[2,133],129:[2,133],130:[2,133],131:[2,133],132:[2,133],133:[2,133],134:[2,133]},{1:[2,113],6:[2,113],25:[2,113],26:[2,113],46:[2,113],51:[2,113],54:[2,113],63:[2,113],64:[2,113],65:[2,113],67:[2,113],69:[2,113],70:[2,113],71:[2,113],75:[2,113],81:[2,113],82:[2,113],83:[2,113],88:[2,113],90:[2,113],99:[2,113],101:[2,113],102:[2,113],103:[2,113],107:[2,113],115:[2,113],123:[2,113],125:[2,113],126:[2,113],129:[2,113],130:[2,113],131:[2,113],132:[2,113],133:[2,113],134:[2,113]},{6:[2,119],25:[2,119],26:[2,119],51:[2,119],83:[2,119],88:[2,119]},{6:[2,49],25:[2,49],26:[2,49],50:305,51:[1,223]},{6:[2,120],25:[2,120],26:[2,120],51:[2,120],83:[2,120],88:[2,120]},{1:[2,158],6:[2,158],25:[2,158],26:[2,158],46:[2,158],51:[2,158],54:[2,158],69:[2,158],75:[2,158],83:[2,158],88:[2,158],90:[2,158],99:[2,158],100:84,101:[2,158],102:[2,158],103:[2,158],106:85,107:[2,158],108:66,115:[1,306],123:[2,158],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,160],6:[2,160],25:[2,160],26:[2,160],46:[2,160],51:[2,160],54:[2,160],69:[2,160],75:[2,160],83:[2,160],88:[2,160],90:[2,160],99:[2,160],100:84,101:[2,160],102:[1,307],103:[2,160],106:85,107:[2,160],108:66,115:[2,160],123:[2,160],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,159],6:[2,159],25:[2,159],26:[2,159],46:[2,159],51:[2,159],54:[2,159],69:[2,159],75:[2,159],83:[2,159],88:[2,159],90:[2,159],99:[2,159],100:84,101:[2,159],102:[2,159],103:[2,159],106:85,107:[2,159],108:66,115:[2,159],123:[2,159],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{6:[2,88],25:[2,88],26:[2,88],51:[2,88],75:[2,88]},{6:[2,49],25:[2,49],26:[2,49],50:308,51:[1,233]},{26:[1,309],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{26:[1,310]},{1:[2,166],6:[2,166],25:[2,166],26:[2,166],46:[2,166],51:[2,166],54:[2,166],69:[2,166],75:[2,166],83:[2,166],88:[2,166],90:[2,166],99:[2,166],101:[2,166],102:[2,166],103:[2,166],107:[2,166],115:[2,166],123:[2,166],125:[2,166],126:[2,166],129:[2,166],130:[2,166],131:[2,166],132:[2,166],133:[2,166],134:[2,166]},{26:[2,170],118:[2,170],120:[2,170]},{25:[2,125],51:[2,125],100:84,101:[1,62],103:[1,63],106:85,107:[1,65],108:66,123:[1,83],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{6:[1,260],25:[1,261],26:[1,311]},{8:312,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:313,9:115,10:19,11:20,12:21,13:[1,22],14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:18,27:59,28:[1,70],29:49,30:[1,68],31:[1,69],32:24,33:[1,50],34:[1,51],35:[1,52],36:23,41:60,42:[1,44],43:[1,46],44:[1,29],47:30,48:[1,57],49:[1,58],55:47,56:48,58:36,60:25,61:26,62:27,73:[1,67],76:[1,43],80:[1,28],85:[1,55],86:[1,56],87:[1,54],93:[1,38],97:[1,45],98:[1,53],100:39,101:[1,62],103:[1,63],104:40,105:[1,64],106:41,107:[1,65],108:66,116:[1,42],121:37,122:[1,61],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[1,271],25:[1,272],26:[1,314]},{6:[2,37],25:[2,37],26:[2,37],51:[2,37],75:[2,37]},{1:[2,164],6:[2,164],25:[2,164],26:[2,164],46:[2,164],51:[2,164],54:[2,164],69:[2,164],75:[2,164],83:[2,164],88:[2,164],90:[2,164],99:[2,164],101:[2,164],102:[2,164],103:[2,164],107:[2,164],115:[2,164],123:[2,164],125:[2,164],126:[2,164],129:[2,164],130:[2,164],131:[2,164],132:[2,164],133:[2,164],134:[2,164]},{6:[2,121],25:[2,121],26:[2,121],51:[2,121],83:[2,121],88:[2,121]},{1:[2,161],6:[2,161],25:[2,161],26:[2,161],46:[2,161],51:[2,161],54:[2,161],69:[2,161],75:[2,161],83:[2,161],88:[2,161],90:[2,161],99:[2,161],100:84,101:[2,161],102:[2,161],103:[2,161],106:85,107:[2,161],108:66,115:[2,161],123:[2,161],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{1:[2,162],6:[2,162],25:[2,162],26:[2,162],46:[2,162],51:[2,162],54:[2,162],69:[2,162],75:[2,162],83:[2,162],88:[2,162],90:[2,162],99:[2,162],100:84,101:[2,162],102:[2,162],103:[2,162],106:85,107:[2,162],108:66,115:[2,162],123:[2,162],125:[1,77],126:[1,76],129:[1,75],130:[1,78],131:[1,79],132:[1,80],133:[1,81],134:[1,82]},{6:[2,89],25:[2,89],26:[2,89],51:[2,89],75:[2,89]}],
+defaultActions: {57:[2,47],58:[2,48],72:[2,3],91:[2,103],186:[2,83]},
+parseError: function parseError(str, hash) {
+ throw new Error(str);
+},
+parse: function parse(input) {
+ var self = this,
+ stack = [0],
+ vstack = [null], // semantic value stack
+ lstack = [], // location stack
+ table = this.table,
+ yytext = '',
+ yylineno = 0,
+ yyleng = 0,
+ recovering = 0,
+ TERROR = 2,
+ EOF = 1;
+
+ //this.reductionCount = this.shiftCount = 0;
+
+ this.lexer.setInput(input);
+ this.lexer.yy = this.yy;
+ this.yy.lexer = this.lexer;
+ if (typeof this.lexer.yylloc == 'undefined')
+ this.lexer.yylloc = {};
+ var yyloc = this.lexer.yylloc;
+ lstack.push(yyloc);
+
+ if (typeof this.yy.parseError === 'function')
+ this.parseError = this.yy.parseError;
+
+ function popStack (n) {
+ stack.length = stack.length - 2*n;
+ vstack.length = vstack.length - n;
+ lstack.length = lstack.length - n;
+ }
+
+ function lex() {
+ var token;
+ token = self.lexer.lex() || 1; // $end = 1
+ // if token isn't its numeric value, convert
+ if (typeof token !== 'number') {
+ token = self.symbols_[token] || token;
+ }
+ return token;
+ };
+
+ var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
+ while (true) {
+ // retreive state number from top of stack
+ state = stack[stack.length-1];
+
+ // use default actions if available
+ if (this.defaultActions[state]) {
+ action = this.defaultActions[state];
+ } else {
+ if (symbol == null)
+ symbol = lex();
+ // read action for current state and first input
+ action = table[state] && table[state][symbol];
+ }
+
+ // handle parse error
+ if (typeof action === 'undefined' || !action.length || !action[0]) {
+
+ if (!recovering) {
+ // Report error
+ expected = [];
+ for (p in table[state]) if (this.terminals_[p] && p > 2) {
+ expected.push("'"+this.terminals_[p]+"'");
+ }
+ var errStr = '';
+ if (this.lexer.showPosition) {
+ errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', ');
+ } else {
+ errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
+ (symbol == 1 /*EOF*/ ? "end of input" :
+ ("'"+(this.terminals_[symbol] || symbol)+"'"));
+ }
+ this.parseError(errStr,
+ {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
+ }
+
+ // just recovered from another error
+ if (recovering == 3) {
+ if (symbol == EOF) {
+ throw new Error(errStr || 'Parsing halted.');
+ }
+
+ // discard current lookahead and grab another
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ symbol = lex();
+ }
+
+ // try to recover from error
+ while (1) {
+ // check for error recovery rule in this state
+ if ((TERROR.toString()) in table[state]) {
+ break;
+ }
+ if (state == 0) {
+ throw new Error(errStr || 'Parsing halted.');
+ }
+ popStack(1);
+ state = stack[stack.length-1];
+ }
+
+ preErrorSymbol = symbol; // save the lookahead token
+ symbol = TERROR; // insert generic error symbol as new lookahead
+ state = stack[stack.length-1];
+ action = table[state] && table[state][TERROR];
+ recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
+ }
+
+ // this shouldn't happen, unless resolve defaults are off
+ if (action[0] instanceof Array && action.length > 1) {
+ throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
+ }
+
+ switch (action[0]) {
+
+ case 1: // shift
+ //this.shiftCount++;
+
+ stack.push(symbol);
+ vstack.push(this.lexer.yytext);
+ lstack.push(this.lexer.yylloc);
+ stack.push(action[1]); // push state
+ symbol = null;
+ if (!preErrorSymbol) { // normal execution/no error
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ if (recovering > 0)
+ recovering--;
+ } else { // error just occurred, resume old lookahead f/ before error
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+
+ case 2: // reduce
+ //this.reductionCount++;
+
+ len = this.productions_[action[1]][1];
+
+ // perform semantic action
+ yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
+ // default location, uses first token for firsts, last for lasts
+ yyval._$ = {
+ first_line: lstack[lstack.length-(len||1)].first_line,
+ last_line: lstack[lstack.length-1].last_line,
+ first_column: lstack[lstack.length-(len||1)].first_column,
+ last_column: lstack[lstack.length-1].last_column
+ };
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
+
+ if (typeof r !== 'undefined') {
+ return r;
+ }
+
+ // pop off stack
+ if (len) {
+ stack = stack.slice(0,-1*len*2);
+ vstack = vstack.slice(0, -1*len);
+ lstack = lstack.slice(0, -1*len);
+ }
+
+ stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
+ vstack.push(yyval.$);
+ lstack.push(yyval._$);
+ // goto new state = table[STATE][NONTERMINAL]
+ newState = table[stack[stack.length-2]][stack[stack.length-1]];
+ stack.push(newState);
+ break;
+
+ case 3: // accept
+ return true;
+ }
+
+ }
+
+ return true;
+}};
+
+module.exports = parser;
+});
\ No newline at end of file
diff --git a/ace/mode/coffee/parser_test.js b/ace/mode/coffee/parser_test.js
new file mode 100644
index 00000000..2515c8e5
--- /dev/null
+++ b/ace/mode/coffee/parser_test.js
@@ -0,0 +1,67 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (typeof process !== "undefined") {
+ require("../../../support/paths");
+}
+
+define(function(require, exports, module) {
+
+var assert = require("ace/test/assertions");
+var coffee = require("ace/mode/coffee/coffee-script");
+
+
+module.exports = {
+
+ "test parse valid coffee script": function() {
+ coffee.parse("square = (x) -> x * x");
+ },
+
+ "test parse invalid coffee script": function() {
+ try {
+ coffee.parse("a = 12 f");
+ } catch (e) {
+ assert.ok((e + "").indexOf("Parse error on line 1: Unexpected 'IDENTIFIER'") >= 0);
+ }
+ }
+};
+
+});
+
+if (typeof module !== "undefined" && module === require.main) {
+ require("asyncjs").test.testcase(module.exports).exec();
+}
\ No newline at end of file
diff --git a/ace/mode/coffee/rewriter.js b/ace/mode/coffee/rewriter.js
new file mode 100644
index 00000000..3e71f078
--- /dev/null
+++ b/ace/mode/coffee/rewriter.js
@@ -0,0 +1,389 @@
+/**
+ * Copyright (c) 2011 Jeremy Ashkenas
+ *
+ * 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.
+ */
+
+define(function(require, exports, module) {
+
+ var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref;
+ var __indexOf = Array.prototype.indexOf || function(item) {
+ for (var i = 0, l = this.length; i < l; i++) {
+ if (this[i] === item) return i;
+ }
+ return -1;
+ }, __slice = Array.prototype.slice;
+ exports.Rewriter = (function() {
+ function Rewriter() {}
+ Rewriter.prototype.rewrite = function(tokens) {
+ this.tokens = tokens;
+ this.removeLeadingNewlines();
+ this.removeMidExpressionNewlines();
+ this.closeOpenCalls();
+ this.closeOpenIndexes();
+ this.addImplicitIndentation();
+ this.tagPostfixConditionals();
+ this.addImplicitBraces();
+ this.addImplicitParentheses();
+ this.ensureBalance(BALANCED_PAIRS);
+ this.rewriteClosingParens();
+ return this.tokens;
+ };
+ Rewriter.prototype.scanTokens = function(block) {
+ var i, token, tokens;
+ tokens = this.tokens;
+ i = 0;
+ while (token = tokens[i]) {
+ i += block.call(this, token, i, tokens);
+ }
+ return true;
+ };
+ Rewriter.prototype.detectEnd = function(i, condition, action) {
+ var levels, token, tokens, _ref, _ref2;
+ tokens = this.tokens;
+ levels = 0;
+ while (token = tokens[i]) {
+ if (levels === 0 && condition.call(this, token, i)) {
+ return action.call(this, token, i);
+ }
+ if (!token || levels < 0) {
+ return action.call(this, token, i - 1);
+ }
+ if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) {
+ levels += 1;
+ } else if (_ref2 = token[0], __indexOf.call(EXPRESSION_END, _ref2) >= 0) {
+ levels -= 1;
+ }
+ i += 1;
+ }
+ return i - 1;
+ };
+ Rewriter.prototype.removeLeadingNewlines = function() {
+ var i, tag, _len, _ref;
+ _ref = this.tokens;
+ for (i = 0, _len = _ref.length; i < _len; i++) {
+ tag = _ref[i][0];
+ if (tag !== 'TERMINATOR') {
+ break;
+ }
+ }
+ if (i) {
+ return this.tokens.splice(0, i);
+ }
+ };
+ Rewriter.prototype.removeMidExpressionNewlines = function() {
+ return this.scanTokens(function(token, i, tokens) {
+ var _ref;
+ if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) {
+ return 1;
+ }
+ tokens.splice(i, 1);
+ return 0;
+ });
+ };
+ Rewriter.prototype.closeOpenCalls = function() {
+ var action, condition;
+ condition = function(token, i) {
+ var _ref;
+ return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')';
+ };
+ action = function(token, i) {
+ return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END';
+ };
+ return this.scanTokens(function(token, i) {
+ if (token[0] === 'CALL_START') {
+ this.detectEnd(i + 1, condition, action);
+ }
+ return 1;
+ });
+ };
+ Rewriter.prototype.closeOpenIndexes = function() {
+ var action, condition;
+ condition = function(token, i) {
+ var _ref;
+ return (_ref = token[0]) === ']' || _ref === 'INDEX_END';
+ };
+ action = function(token, i) {
+ return token[0] = 'INDEX_END';
+ };
+ return this.scanTokens(function(token, i) {
+ if (token[0] === 'INDEX_START') {
+ this.detectEnd(i + 1, condition, action);
+ }
+ return 1;
+ });
+ };
+ Rewriter.prototype.addImplicitBraces = function() {
+ var action, condition, stack, start, startIndent;
+ stack = [];
+ start = null;
+ startIndent = 0;
+ condition = function(token, i) {
+ var one, tag, three, two, _ref, _ref2;
+ _ref = this.tokens.slice(i + 1, (i + 3 + 1) || 9e9), one = _ref[0], two = _ref[1], three = _ref[2];
+ if ('HERECOMMENT' === (one != null ? one[0] : void 0)) {
+ return false;
+ }
+ tag = token[0];
+ return ((tag === 'TERMINATOR' || tag === 'OUTDENT') && !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':')) || (tag === ',' && one && ((_ref2 = one[0]) !== 'IDENTIFIER' && _ref2 !== 'NUMBER' && _ref2 !== 'STRING' && _ref2 !== '@' && _ref2 !== 'TERMINATOR' && _ref2 !== 'OUTDENT'));
+ };
+ action = function(token, i) {
+ var tok;
+ tok = ['}', '}', token[2]];
+ tok.generated = true;
+ return this.tokens.splice(i, 0, tok);
+ };
+ return this.scanTokens(function(token, i, tokens) {
+ var ago, idx, tag, tok, value, _ref, _ref2;
+ if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
+ stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]);
+ return 1;
+ }
+ if (__indexOf.call(EXPRESSION_END, tag) >= 0) {
+ start = stack.pop();
+ return 1;
+ }
+ if (!(tag === ':' && ((ago = this.tag(i - 2)) === ':' || ((_ref2 = stack[stack.length - 1]) != null ? _ref2[0] : void 0) !== '{'))) {
+ return 1;
+ }
+ stack.push(['{']);
+ idx = ago === '@' ? i - 2 : i - 1;
+ while (this.tag(idx - 2) === 'HERECOMMENT') {
+ idx -= 2;
+ }
+ value = new String('{');
+ value.generated = true;
+ tok = ['{', value, token[2]];
+ tok.generated = true;
+ tokens.splice(idx, 0, tok);
+ this.detectEnd(i + 2, condition, action);
+ return 2;
+ });
+ };
+ Rewriter.prototype.addImplicitParentheses = function() {
+ var action, noCall;
+ noCall = false;
+ action = function(token, i) {
+ var idx;
+ idx = token[0] === 'OUTDENT' ? i + 1 : i;
+ return this.tokens.splice(idx, 0, ['CALL_END', ')', token[2]]);
+ };
+ return this.scanTokens(function(token, i, tokens) {
+ var callObject, current, next, prev, seenControl, seenSingle, tag, _ref, _ref2, _ref3;
+ tag = token[0];
+ if (tag === 'CLASS' || tag === 'IF') {
+ noCall = true;
+ }
+ _ref = tokens.slice(i - 1, (i + 1 + 1) || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2];
+ callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0);
+ seenSingle = false;
+ seenControl = false;
+ if (__indexOf.call(LINEBREAKS, tag) >= 0) {
+ noCall = false;
+ }
+ if (prev && !prev.spaced && tag === '?') {
+ token.call = true;
+ }
+ if (token.fromThen) {
+ return 1;
+ }
+ if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref3 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref3) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) {
+ return 1;
+ }
+ tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
+ this.detectEnd(i + 1, function(token, i) {
+ var post, _ref4;
+ tag = token[0];
+ if (!seenSingle && token.fromThen) {
+ return true;
+ }
+ if (tag === 'IF' || tag === 'ELSE' || tag === 'CATCH' || tag === '->' || tag === '=>') {
+ seenSingle = true;
+ }
+ if (tag === 'IF' || tag === 'ELSE' || tag === 'SWITCH' || tag === 'TRY') {
+ seenControl = true;
+ }
+ if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') {
+ return true;
+ }
+ return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (this.tag(i - 2) !== 'CLASS' && (_ref4 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref4) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
+ }, action);
+ if (prev[0] === '?') {
+ prev[0] = 'FUNC_EXIST';
+ }
+ return 2;
+ });
+ };
+ Rewriter.prototype.addImplicitIndentation = function() {
+ return this.scanTokens(function(token, i, tokens) {
+ var action, condition, indent, outdent, starter, tag, _ref, _ref2;
+ tag = token[0];
+ if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') {
+ tokens.splice(i, 1);
+ return 0;
+ }
+ if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
+ tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation(token))));
+ return 2;
+ }
+ if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) {
+ tokens.splice.apply(tokens, [i + 2, 0].concat(__slice.call(this.indentation(token))));
+ return 4;
+ }
+ if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
+ starter = tag;
+ _ref2 = this.indentation(token), indent = _ref2[0], outdent = _ref2[1];
+ if (starter === 'THEN') {
+ indent.fromThen = true;
+ }
+ indent.generated = outdent.generated = true;
+ tokens.splice(i + 1, 0, indent);
+ condition = function(token, i) {
+ var _ref3;
+ return token[1] !== ';' && (_ref3 = token[0], __indexOf.call(SINGLE_CLOSERS, _ref3) >= 0) && !(token[0] === 'ELSE' && (starter !== 'IF' && starter !== 'THEN'));
+ };
+ action = function(token, i) {
+ return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent);
+ };
+ this.detectEnd(i + 2, condition, action);
+ if (tag === 'THEN') {
+ tokens.splice(i, 1);
+ }
+ return 1;
+ }
+ return 1;
+ });
+ };
+ Rewriter.prototype.tagPostfixConditionals = function() {
+ var condition;
+ condition = function(token, i) {
+ var _ref;
+ return (_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT';
+ };
+ return this.scanTokens(function(token, i) {
+ var original;
+ if (token[0] !== 'IF') {
+ return 1;
+ }
+ original = token;
+ this.detectEnd(i + 1, condition, function(token, i) {
+ if (token[0] !== 'INDENT') {
+ return original[0] = 'POST_' + original[0];
+ }
+ });
+ return 1;
+ });
+ };
+ Rewriter.prototype.ensureBalance = function(pairs) {
+ var close, level, levels, open, openLine, tag, token, _i, _j, _len, _len2, _ref, _ref2;
+ levels = {};
+ openLine = {};
+ _ref = this.tokens;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ token = _ref[_i];
+ tag = token[0];
+ for (_j = 0, _len2 = pairs.length; _j < _len2; _j++) {
+ _ref2 = pairs[_j], open = _ref2[0], close = _ref2[1];
+ levels[open] |= 0;
+ if (tag === open) {
+ if (levels[open]++ === 0) {
+ openLine[open] = token[2];
+ }
+ } else if (tag === close && --levels[open] < 0) {
+ throw Error("too many " + token[1] + " on line " + (token[2] + 1));
+ }
+ }
+ }
+ for (open in levels) {
+ level = levels[open];
+ if (level > 0) {
+ throw Error("unclosed " + open + " on line " + (openLine[open] + 1));
+ }
+ }
+ return this;
+ };
+ Rewriter.prototype.rewriteClosingParens = function() {
+ var debt, key, stack;
+ stack = [];
+ debt = {};
+ for (key in INVERSES) {
+ debt[key] = 0;
+ }
+ return this.scanTokens(function(token, i, tokens) {
+ var inv, match, mtag, oppos, tag, val, _ref;
+ if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
+ stack.push(token);
+ return 1;
+ }
+ if (__indexOf.call(EXPRESSION_END, tag) < 0) {
+ return 1;
+ }
+ if (debt[inv = INVERSES[tag]] > 0) {
+ debt[inv] -= 1;
+ tokens.splice(i, 1);
+ return 0;
+ }
+ match = stack.pop();
+ mtag = match[0];
+ oppos = INVERSES[mtag];
+ if (tag === oppos) {
+ return 1;
+ }
+ debt[mtag] += 1;
+ val = [oppos, mtag === 'INDENT' ? match[1] : oppos];
+ if (this.tag(i + 2) === mtag) {
+ tokens.splice(i + 3, 0, val);
+ stack.push(match);
+ } else {
+ tokens.splice(i, 0, val);
+ }
+ return 1;
+ });
+ };
+ Rewriter.prototype.indentation = function(token) {
+ return [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]];
+ };
+ Rewriter.prototype.tag = function(i) {
+ var _ref;
+ return (_ref = this.tokens[i]) != null ? _ref[0] : void 0;
+ };
+ return Rewriter;
+ })();
+ BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']];
+ INVERSES = {};
+ EXPRESSION_START = [];
+ EXPRESSION_END = [];
+ for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) {
+ _ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1];
+ EXPRESSION_START.push(INVERSES[rite] = left);
+ EXPRESSION_END.push(INVERSES[left] = rite);
+ }
+ EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
+ IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
+ IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++'];
+ IMPLICIT_UNSPACED_CALL = ['+', '-'];
+ IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','];
+ IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR'];
+ SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
+ SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN'];
+ LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'];
+});
diff --git a/lib/ace/mode/coffee/scope.js b/ace/mode/coffee/scope.js
similarity index 68%
rename from lib/ace/mode/coffee/scope.js
rename to ace/mode/coffee/scope.js
index 5834963b..f0a30da9 100644
--- a/lib/ace/mode/coffee/scope.js
+++ b/ace/mode/coffee/scope.js
@@ -1,6 +1,6 @@
/**
- * Copyright (c) 2009-2013 Jeremy Ashkenas
- *
+ * Copyright (c) 2011 Jeremy Ashkenas
+ *
* 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
@@ -21,19 +21,13 @@
* 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.
- *
*/
define(function(require, exports, module) {
-// Generated by CoffeeScript 1.6.3
-
var Scope, extend, last, _ref;
-
- _ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
-
+ _ref = require('ace/mode/coffee/helpers'), extend = _ref.extend, last = _ref.last;
exports.Scope = Scope = (function() {
Scope.root = null;
-
function Scope(parent, expressions, method) {
this.parent = parent;
this.expressions = expressions;
@@ -49,13 +43,13 @@ define(function(require, exports, module) {
Scope.root = this;
}
}
-
Scope.prototype.add = function(name, type, immediate) {
+ var pos;
if (this.shared && !immediate) {
return this.parent.add(name, type, immediate);
}
- if (Object.prototype.hasOwnProperty.call(this.positions, name)) {
- return this.variables[this.positions[name]].type = type;
+ if (typeof (pos = this.positions[name]) === 'number') {
+ return this.variables[pos].type = type;
} else {
return this.positions[name] = this.variables.push({
name: name,
@@ -63,112 +57,89 @@ define(function(require, exports, module) {
}) - 1;
}
};
-
- Scope.prototype.namedMethod = function() {
- var _ref1;
- if (((_ref1 = this.method) != null ? _ref1.name : void 0) || !this.parent) {
- return this.method;
- }
- return this.parent.namedMethod();
- };
-
- Scope.prototype.find = function(name) {
- if (this.check(name)) {
+ Scope.prototype.find = function(name, options) {
+ if (this.check(name, options)) {
return true;
}
this.add(name, 'var');
return false;
};
-
Scope.prototype.parameter = function(name) {
if (this.shared && this.parent.check(name, true)) {
return;
}
return this.add(name, 'param');
};
-
- Scope.prototype.check = function(name) {
- var _ref1;
- return !!(this.type(name) || ((_ref1 = this.parent) != null ? _ref1.check(name) : void 0));
+ Scope.prototype.check = function(name, immediate) {
+ var found, _ref2;
+ found = !!this.type(name);
+ if (found || immediate) {
+ return found;
+ }
+ return !!((_ref2 = this.parent) != null ? _ref2.check(name) : void 0);
};
-
Scope.prototype.temporary = function(name, index) {
if (name.length > 1) {
- return '_' + name + (index > 1 ? index - 1 : '');
+ return '_' + name + (index > 1 ? index : '');
} else {
return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a');
}
};
-
Scope.prototype.type = function(name) {
- var v, _i, _len, _ref1;
- _ref1 = this.variables;
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- v = _ref1[_i];
+ var v, _i, _len, _ref2;
+ _ref2 = this.variables;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ v = _ref2[_i];
if (v.name === name) {
return v.type;
}
}
return null;
};
-
- Scope.prototype.freeVariable = function(name, reserve) {
+ Scope.prototype.freeVariable = function(type) {
var index, temp;
- if (reserve == null) {
- reserve = true;
- }
index = 0;
- while (this.check((temp = this.temporary(name, index)))) {
+ while (this.check((temp = this.temporary(type, index)))) {
index++;
}
- if (reserve) {
- this.add(temp, 'var', true);
- }
+ this.add(temp, 'var', true);
return temp;
};
-
Scope.prototype.assign = function(name, value) {
this.add(name, {
value: value,
assigned: true
- }, true);
+ });
return this.hasAssignments = true;
};
-
Scope.prototype.hasDeclarations = function() {
return !!this.declaredVariables().length;
};
-
Scope.prototype.declaredVariables = function() {
- var realVars, tempVars, v, _i, _len, _ref1;
+ var realVars, tempVars, v, _i, _len, _ref2;
realVars = [];
tempVars = [];
- _ref1 = this.variables;
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- v = _ref1[_i];
+ _ref2 = this.variables;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ v = _ref2[_i];
if (v.type === 'var') {
(v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name);
}
}
return realVars.sort().concat(tempVars.sort());
};
-
Scope.prototype.assignedVariables = function() {
- var v, _i, _len, _ref1, _results;
- _ref1 = this.variables;
+ var v, _i, _len, _ref2, _results;
+ _ref2 = this.variables;
_results = [];
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- v = _ref1[_i];
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ v = _ref2[_i];
if (v.type.assigned) {
_results.push("" + v.name + " = " + v.type.value);
}
}
return _results;
};
-
return Scope;
-
})();
-
-
-});
\ No newline at end of file
+});
diff --git a/ace/mode/coffee_highlight_rules.js b/ace/mode/coffee_highlight_rules.js
new file mode 100644
index 00000000..04742b1b
--- /dev/null
+++ b/ace/mode/coffee_highlight_rules.js
@@ -0,0 +1,196 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Satoshi Murakami
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+ require("ace/lib/oop").inherits(
+ CoffeeHighlightRules,
+ require("ace/mode/text_highlight_rules").TextHighlightRules
+ );
+
+ function CoffeeHighlightRules() {
+ var identifier = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*";
+ var keywordend = "(?![$\\w]|\\s*:)";
+ var stringfill = {
+ token : "string",
+ merge : true,
+ regex : ".+"
+ };
+
+ this.$rules = {
+ start : [
+ {
+ token : "identifier",
+ regex : "(?:@|(?:\\.|::)\\s*)" + identifier
+ }, {
+ token : "keyword",
+ regex : "(?:t(?:h(?:is|row|en)|ry|ypeof)|s(?:uper|witch)|return|b(?:reak|y)|c(?:ontinue|atch|lass)|i(?:n(?:stanceof)?|s(?:nt)?|f)|e(?:lse|xtends)|f(?:or (?:own)?|inally|unction)|wh(?:ile|en)|n(?:ew|ot?)|d(?:e(?:lete|bugger)|o)|loop|o(?:ff?|[rn])|un(?:less|til)|and|yes)"
+ + keywordend
+ }, {
+ token : "constant.language",
+ regex : "(?:true|false|null|undefined)" + keywordend
+ }, {
+ token : "invalid.illegal",
+ regex : "(?:c(?:ase|onst)|default|function|v(?:ar|oid)|with|e(?:num|xport)|i(?:mplements|nterface)|let|p(?:ackage|r(?:ivate|otected)|ublic)|static|yield|__(?:hasProp|extends|slice|bind|indexOf))"
+ + keywordend
+ }, {
+ token : "language.support.class",
+ regex : "(?:Array|Boolean|Date|Function|Number|Object|R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|TypeError|URIError)"
+ + keywordend
+ }, {
+ token : "language.support.function",
+ regex : "(?:Math|JSON|is(?:NaN|Finite)|parse(?:Int|Float)|encodeURI(?:Component)?|decodeURI(?:Component)?)"
+ + keywordend
+ }, {
+ token : "identifier",
+ regex : identifier
+ }, {
+ token : "constant.numeric",
+ regex : "(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)"
+ }, {
+ token : "string",
+ merge : true,
+ regex : "'''",
+ next : "qdoc"
+ }, {
+ token : "string",
+ merge : true,
+ regex : '"""',
+ next : "qqdoc"
+ }, {
+ token : "string",
+ merge : true,
+ regex : "'",
+ next : "qstring"
+ }, {
+ token : "string",
+ merge : true,
+ regex : '"',
+ next : "qqstring"
+ }, {
+ token : "string",
+ merge : true,
+ regex : "`",
+ next : "js"
+ }, {
+ token : "string.regex",
+ merge : true,
+ regex : "///",
+ next : "heregex"
+ }, {
+ token : "string.regex",
+ regex : "/(?!\\s)[^[/\\n\\\\]*(?: (?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[/\\n\\\\]*)*/[imgy]{0,4}(?!\\w)"
+ }, {
+ token : "comment",
+ merge : true,
+ regex : "###(?!#)",
+ next : "comment"
+ }, {
+ token : "comment",
+ regex : "#.*"
+ }, {
+ token : "lparen",
+ regex : "[({[]"
+ }, {
+ token : "rparen",
+ regex : "[\\]})]"
+ }, {
+ token : "keyword.operator",
+ regex : "\\S+"
+ }, {
+ token : "text",
+ regex : "\\s+"
+ }],
+
+ qdoc : [{
+ token : "string",
+ regex : ".*?'''",
+ next : "start"
+ }, stringfill],
+
+ qqdoc : [{
+ token : "string",
+ regex : '.*?"""',
+ next : "start"
+ }, stringfill],
+
+ qstring : [{
+ token : "string",
+ regex : "[^\\\\']*(?:\\\\.[^\\\\']*)*'",
+ next : "start"
+ }, stringfill],
+
+ qqstring : [{
+ token : "string",
+ regex : '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',
+ next : "start"
+ }, stringfill],
+
+ js : [{
+ token : "string",
+ merge : true,
+ regex : "[^\\\\`]*(?:\\\\.[^\\\\`]*)*`",
+ next : "start"
+ }, stringfill],
+
+ heregex : [{
+ token : "string.regex",
+ regex : '.*?///[imgy]{0,4}',
+ next : "start"
+ }, {
+ token : "comment.regex",
+ regex : "\\s+(?:#.*)?"
+ }, {
+ token : "string.regex",
+ merge : true,
+ regex : "\\S+"
+ }],
+
+ comment : [{
+ token : "comment",
+ regex : '.*?###',
+ next : "start"
+ }, {
+ token : "comment",
+ merge : true,
+ regex : ".+"
+ }]
+ };
+ }
+
+ exports.CoffeeHighlightRules = CoffeeHighlightRules;
+});
diff --git a/ace/mode/coffee_worker.js b/ace/mode/coffee_worker.js
new file mode 100644
index 00000000..ef39e0ac
--- /dev/null
+++ b/ace/mode/coffee_worker.js
@@ -0,0 +1,91 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var Mirror = require("ace/worker/mirror").Mirror;
+var coffee = require("ace/mode/coffee/coffee-script");
+
+window.addEventListener = function() {};
+
+
+var Worker = exports.Worker = function(sender) {
+ Mirror.call(this, sender);
+ this.setTimeout(200);
+};
+
+oop.inherits(Worker, Mirror);
+
+(function() {
+
+ this.onUpdate = function() {
+ var value = this.doc.getValue();
+
+ try {
+ coffee.parse(value);
+ } catch(e) {
+ var m = e.message.match(/Parse error on line (\d+): (.*)/);
+ if (m) {
+ this.sender.emit("error", {
+ row: parseInt(m[1]) - 1,
+ column: null,
+ text: m[2],
+ type: "error"
+ });
+ return;
+ }
+
+ if (e instanceof SyntaxError) {
+ var m = e.message.match(/ on line (\d+)/);
+ if (m) {
+ this.sender.emit("error", {
+ row: parseInt(m[1]) - 1,
+ column: null,
+ text: e.message.replace(m[0], ""),
+ type: "error"
+ });
+ }
+ }
+ return;
+ }
+ this.sender.emit("ok");
+ };
+
+}).call(Worker.prototype);
+
+});
\ No newline at end of file
diff --git a/ace/mode/csharp.js b/ace/mode/csharp.js
new file mode 100644
index 00000000..5750d7d1
--- /dev/null
+++ b/ace/mode/csharp.js
@@ -0,0 +1,56 @@
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var TextMode = require("ace/mode/text").Mode;
+var Tokenizer = require("ace/tokenizer").Tokenizer;
+var CSharpHighlightRules = require("ace/mode/csharp_highlight_rules").CSharpHighlightRules;
+var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
+var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour;
+
+var Mode = function() {
+ this.$tokenizer = new Tokenizer(new CSharpHighlightRules().getRules());
+ this.$outdent = new MatchingBraceOutdent();
+ this.$behaviour = new CstyleBehaviour();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+
+ var tokenizedLine = this.$tokenizer.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.createWorker = function(session) {
+ return null;
+ };
+
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+});
diff --git a/lib/ace/mode/haxe_highlight_rules.js b/ace/mode/csharp_highlight_rules.js
similarity index 54%
rename from lib/ace/mode/haxe_highlight_rules.js
rename to ace/mode/csharp_highlight_rules.js
index e9956136..c85cf957 100644
--- a/lib/ace/mode/haxe_highlight_rules.js
+++ b/ace/mode/csharp_highlight_rules.js
@@ -1,26 +1,20 @@
define(function(require, exports, module) {
-"use strict";
-var oop = require("../lib/oop");
+var oop = require("ace/lib/oop");
+var lang = require("ace/lib/lang");
+var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules;
+var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;
-var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
-var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
-
-var HaxeHighlightRules = function() {
-
- var keywords = (
- "break|case|cast|catch|class|continue|default|else|enum|extends|for|function|if|implements|import|in|inline|interface|new|override|package|private|public|return|static|super|switch|this|throw|trace|try|typedef|untyped|var|while|Array|Void|Bool|Int|UInt|Float|Dynamic|String|List|Hash|IntHash|Error|Unknown|Type|Std"
+var CSharpHighlightRules = function() {
+
+ var keywords = lang.arrayToMap(
+ ("abstract|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic").split("|")
);
- var buildinConstants = (
- "null|true|false"
+ var buildinConstants = lang.arrayToMap(
+ ("null|true|false").split("|")
);
- var keywordMapper = this.createKeywordMapper({
- "variable.language": "this",
- "keyword": keywords,
- "constant.language": buildinConstants
- }, "identifier");
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
@@ -31,10 +25,11 @@ var HaxeHighlightRules = function() {
token : "comment",
regex : "\\/\\/.*$"
},
- DocCommentHighlightRules.getStartRule("doc-start"),
+ new DocCommentHighlightRules().getStartRule("doc-start"),
{
token : "comment", // multi line comment
regex : "\\/\\*",
+ merge : true,
next : "comment"
}, {
token : "string.regexp",
@@ -55,7 +50,16 @@ var HaxeHighlightRules = function() {
token : "constant.language.boolean",
regex : "(?:true|false)\\b"
}, {
- token : keywordMapper,
+ token : function(value) {
+ if (value == "this")
+ return "variable.language";
+ else if (keywords.hasOwnProperty(value))
+ return "keyword";
+ else if (buildinConstants.hasOwnProperty(value))
+ return "constant.language";
+ else
+ return "identifier";
+ },
// TODO: Unicode escape sequences
// TODO: Unicode identifiers
regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
@@ -63,14 +67,11 @@ var HaxeHighlightRules = function() {
token : "keyword.operator",
regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
}, {
- token : "punctuation.operator",
- regex : "\\?|\\:|\\,|\\;|\\."
+ token : "lparen",
+ regex : "[[({]"
}, {
- token : "paren.lparen",
- regex : "[[({<]"
- }, {
- token : "paren.rparen",
- regex : "[\\])}>]"
+ token : "rparen",
+ regex : "[\\])}]"
}, {
token : "text",
regex : "\\s+"
@@ -83,16 +84,17 @@ var HaxeHighlightRules = function() {
next : "start"
}, {
token : "comment", // comment spanning whole line
+ merge : true,
regex : ".+"
}
]
};
-
+
this.embedRules(DocCommentHighlightRules, "doc-",
- [ DocCommentHighlightRules.getEndRule("start") ]);
+ [ new DocCommentHighlightRules().getEndRule("start") ]);
};
-oop.inherits(HaxeHighlightRules, TextHighlightRules);
+oop.inherits(CSharpHighlightRules, TextHighlightRules);
-exports.HaxeHighlightRules = HaxeHighlightRules;
+exports.CSharpHighlightRules = CSharpHighlightRules;
});
diff --git a/ace/mode/css.js b/ace/mode/css.js
new file mode 100644
index 00000000..80960fbb
--- /dev/null
+++ b/ace/mode/css.js
@@ -0,0 +1,113 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Ajax.org Code Editor (ACE).
+ *
+ * The Initial Developer of the Original Code is
+ * Ajax.org B.V.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var oop = require("ace/lib/oop");
+var TextMode = require("ace/mode/text").Mode;
+var Tokenizer = require("ace/tokenizer").Tokenizer;
+var CssHighlightRules = require("ace/mode/css_highlight_rules").CssHighlightRules;
+var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
+var WorkerClient = require("ace/worker/worker_client").WorkerClient;
+
+var Mode = function() {
+ this.$tokenizer = new Tokenizer(new CssHighlightRules().getRules());
+ this.$outdent = new MatchingBraceOutdent();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+
+ // ignore braces in comments
+ var tokens = this.$tokenizer.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.createWorker = function(session) {
+ var doc = session.getDocument();
+ var worker = new WorkerClient(["ace"], "worker-css.js", "ace/mode/css_worker", "Worker");
+ worker.call("setValue", [doc.getValue()]);
+
+ doc.on("change", function(e) {
+ e.range = {
+ start: e.data.range.start,
+ end: e.data.range.end
+ };
+ worker.emit("change", e);
+ });
+
+ worker.on("csslint", function(e) {
+ var errors = [];
+ e.data.forEach(function(message) {
+ errors.push({
+ row: message.line - 1,
+ column: message.col - 1,
+ text: message.message,
+ type: message.type,
+ lint: message
+ });
+ });
+
+ session.setAnnotations(errors);
+ });
+ };
+
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+
+});
diff --git a/lib/ace/mode/css/csslint.js b/ace/mode/css/csslint.js
similarity index 56%
rename from lib/ace/mode/css/csslint.js
rename to ace/mode/css/csslint.js
index c3c79a80..2c80f22c 100644
--- a/lib/ace/mode/css/csslint.js
+++ b/ace/mode/css/csslint.js
@@ -1,10 +1,9 @@
-define(function(require, exports, module) {
-/*!
+/*
CSSLint
-Copyright (c) 2014 Nicole Sullivan and Nicholas C. Zakas. All rights reserved.
+Copyright (c) 2011 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
+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
@@ -13,7 +12,7 @@ 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
+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
@@ -22,7 +21,7 @@ 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 */
+define(function(require, exports, module) {
/*!
Parser-Lib
Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.
@@ -46,7 +45,7 @@ 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 */
+/* Build time: 13-July-2011 04:35:28 */
var parserlib = {};
(function(){
@@ -64,7 +63,7 @@ function EventTarget(){
* @property _listeners
* @private
*/
- this._listeners = {};
+ this._listeners = {};
}
EventTarget.prototype = {
@@ -86,34 +85,34 @@ EventTarget.prototype = {
this._listeners[type].push(listener);
},
-
+
/**
* 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 };
}
- if (typeof event.target != "undefined"){
+ if (!event.target){
event.target = this;
}
-
- if (typeof event.type == "undefined"){
+
+ if (!event.type){
throw new Error("Event object missing 'type' property.");
}
-
+
if (this._listeners[event.type]){
-
+
//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);
}
- }
+ }
},
/**
@@ -132,9 +131,9 @@ EventTarget.prototype = {
break;
}
}
-
-
- }
+
+
+ }
}
};
/**
@@ -449,7 +448,7 @@ SyntaxError.prototype = new Error();
* @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){
+function SyntaxUnit(text, line, col){
/**
@@ -473,12 +472,6 @@ function SyntaxUnit(text, line, col, type){
*/
this.text = text;
- /**
- * The type of syntax unit.
- * @type int
- * @property type
- */
- this.type = type;
}
/**
@@ -498,16 +491,16 @@ SyntaxUnit.prototype = {
//restore constructor
constructor: SyntaxUnit,
-
+
/**
* Returns the text representation of the unit.
* @return {String} The text representation of the unit.
* @method valueOf
*/
valueOf: function(){
- return this.text;
+ return this.toString();
},
-
+
/**
* Returns the text representation of the unit.
* @return {String} The text representation of the unit.
@@ -518,14 +511,12 @@ SyntaxUnit.prototype = {
}
};
-/*global StringReader, SyntaxError*/
-
/**
* Generic TokenStream providing base functionality.
* @class TokenStreamBase
* @namespace parserlib.util
* @constructor
- * @param {String|StringReader} input The text to tokenize or a reader from
+ * @param {String|StringReader} input The text to tokenize or a reader from
* which to read the input.
*/
function TokenStreamBase(input, tokenData){
@@ -536,16 +527,17 @@ function TokenStreamBase(input, tokenData){
* @property _reader
* @private
*/
+ //this._reader = (typeof input == "string") ? new StringReader(input) : input;
this._reader = input ? new StringReader(input.toString()) : null;
-
+
/**
* Token object for the last consumed token.
* @type Token
* @property _token
* @private
*/
- this._token = null;
-
+ this._token = null;
+
/**
* The array of token information.
* @type Array
@@ -553,7 +545,7 @@ function TokenStreamBase(input, tokenData){
* @private
*/
this._tokenData = tokenData;
-
+
/**
* Lookahead token buffer.
* @type Array
@@ -561,7 +553,7 @@ function TokenStreamBase(input, tokenData){
* @private
*/
this._lt = [];
-
+
/**
* Lookahead token buffer index.
* @type int
@@ -569,7 +561,7 @@ function TokenStreamBase(input, tokenData){
* @private
*/
this._ltIndex = 0;
-
+
this._ltIndexCache = [];
}
@@ -584,14 +576,14 @@ function TokenStreamBase(input, tokenData){
*/
TokenStreamBase.createTokenData = function(tokens){
- var nameMap = [],
- typeMap = {},
- tokenData = tokens.concat([]),
- i = 0,
- len = tokenData.length+1;
-
+ var nameMap = [],
+ typeMap = {},
+ tokenData = tokens.concat([]),
+ i = 0,
+ len = tokenData.length+1;
+
tokenData.UNKNOWN = -1;
- tokenData.unshift({name:"EOF"});
+ tokenData.unshift({name:"EOF"});
for (; i < len; i++){
nameMap.push(tokenData[i].name);
@@ -600,27 +592,27 @@ TokenStreamBase.createTokenData = function(tokens){
typeMap[tokenData[i].text] = i;
}
}
-
+
tokenData.name = function(tt){
return nameMap[tt];
};
-
+
tokenData.type = function(c){
return typeMap[c];
};
-
- return tokenData;
+
+ return tokenData;
};
TokenStreamBase.prototype = {
//restore constructor
- constructor: TokenStreamBase,
-
+ constructor: TokenStreamBase,
+
//-------------------------------------------------------------------------
// Matching methods
//-------------------------------------------------------------------------
-
+
/**
* Determines if the next token matches the given token type.
* If so, that token is consumed; if not, the token is placed
@@ -636,27 +628,27 @@ TokenStreamBase.prototype = {
* @method match
*/
match: function(tokenTypes, channel){
-
+
//always convert to an array, makes things easier
if (!(tokenTypes instanceof Array)){
tokenTypes = [tokenTypes];
}
-
+
var tt = this.get(channel),
i = 0,
len = tokenTypes.length;
-
+
while(i < len){
if (tt == tokenTypes[i++]){
return true;
}
}
-
+
//no match found, put the token back
this.unget();
return false;
- },
-
+ },
+
/**
* Determines if the next token matches the given token type.
* If so, that token is consumed; if not, an error is thrown.
@@ -667,27 +659,25 @@ TokenStreamBase.prototype = {
* provided, reads from the default (unnamed) channel.
* @return {void}
* @method mustMatch
- */
+ */
mustMatch: function(tokenTypes, channel){
- var token;
-
//always convert to an array, makes things easier
if (!(tokenTypes instanceof Array)){
tokenTypes = [tokenTypes];
}
- if (!this.match.apply(this, arguments)){
+ if (!this.match.apply(this, arguments)){
token = this.LT(1);
- throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name +
+ throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name +
" at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
}
},
-
+
//-------------------------------------------------------------------------
// Consuming methods
//-------------------------------------------------------------------------
-
+
/**
* 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.
@@ -700,21 +690,21 @@ TokenStreamBase.prototype = {
* @method advance
*/
advance: function(tokenTypes, channel){
-
- while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){
+
+ while(this.LA(0) != 0 && !this.match(tokenTypes, channel)){
this.get();
}
- return this.LA(0);
+ return this.LA(0);
},
-
+
/**
- * Consumes the next token from the token stream.
+ * 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){
-
+
var tokenInfo = this._tokenData,
reader = this._reader,
value,
@@ -723,14 +713,14 @@ TokenStreamBase.prototype = {
found = false,
token,
info;
-
+
//check the lookahead buffer first
- if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){
-
+ if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){
+
i++;
this._token = this._lt[this._ltIndex++];
info = tokenInfo[this._token.type];
-
+
//obey channels logic
while((info.channel !== undefined && channel !== info.channel) &&
this._ltIndex < this._lt.length){
@@ -738,7 +728,7 @@ TokenStreamBase.prototype = {
info = tokenInfo[this._token.type];
i++;
}
-
+
//here be dragons
if ((info.channel === undefined || channel === info.channel) &&
this._ltIndex <= this._lt.length){
@@ -746,45 +736,45 @@ TokenStreamBase.prototype = {
return this._token.type;
}
}
-
+
//call token retriever method
- token = this._getToken();
+ token = this._getToken();
//if it should be hidden, don't save a token
if (token.type > -1 && !tokenInfo[token.type].hide){
-
+
//apply token channel
token.channel = tokenInfo[token.type].channel;
-
+
//save for later
this._token = token;
this._lt.push(token);
//save space that will be moved (must be done before array is truncated)
- this._ltIndexCache.push(this._lt.length - this._ltIndex + i);
-
+ this._ltIndexCache.push(this._lt.length - this._ltIndex + i);
+
//keep the buffer under 5 items
if (this._lt.length > 5){
- this._lt.shift();
+ this._lt.shift();
}
-
+
//also keep the shift buffer under 5 items
if (this._ltIndexCache.length > 5){
this._ltIndexCache.shift();
}
-
+
//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 ||
+ if (info &&
+ (info.hide ||
(info.channel !== undefined && channel !== info.channel))){
return this.get(channel);
} else {
@@ -792,7 +782,7 @@ TokenStreamBase.prototype = {
return token.type;
}
},
-
+
/**
* 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
@@ -811,34 +801,34 @@ TokenStreamBase.prototype = {
if (index > 5){
throw new Error("Too much lookahead.");
}
-
+
//get all those tokens
while(total){
- tt = this.get();
- total--;
+ tt = this.get();
+ total--;
}
-
+
//unget all those tokens
while(total < index){
this.unget();
total++;
}
} else if (index < 0){
-
+
if(this._lt[this._ltIndex+index]){
tt = this._lt[this._ltIndex+index].type;
} else {
throw new Error("Too much lookbehind.");
}
-
+
} else {
tt = this._token.type;
}
-
+
return tt;
-
+
},
-
+
/**
* Looks ahead a certain number of tokens and returns the token at
* that position. This will throw an error if you lookahead past the
@@ -848,18 +838,18 @@ TokenStreamBase.prototype = {
* 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){
-
+
//lookahead first to prime the token buffer
this.LA(index);
-
+
//now find the token, subtract one because _ltIndex is already at the next index
- return this._lt[this._ltIndex+index-1];
+ return this._lt[this._ltIndex+index-1];
},
-
+
/**
- * Returns the token type for the next token in the stream without
+ * 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
@@ -867,7 +857,7 @@ TokenStreamBase.prototype = {
peek: function(){
return this.LA(1);
},
-
+
/**
* Returns the actual token object for the last consumed token.
* @return {Token} The token object for the last consumed token.
@@ -876,7 +866,7 @@ TokenStreamBase.prototype = {
token: function(){
return this._token;
},
-
+
/**
* Returns the name of the token for the given token type.
* @param {int} tokenType The type of token to get the name of.
@@ -891,22 +881,22 @@ TokenStreamBase.prototype = {
return this._tokenData[tokenType].name;
}
},
-
+
/**
* 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;
},
-
+
/**
* Returns the last consumed token to the token stream.
* @method unget
- */
+ */
unget: function(){
//if (this._ltIndex > -1){
if (this._ltIndexCache.length){
@@ -920,6 +910,7 @@ TokenStreamBase.prototype = {
};
+
parserlib.util = {
StringReader: StringReader,
SyntaxError : SyntaxError,
@@ -928,7 +919,8 @@ EventTarget : EventTarget,
TokenStreamBase : TokenStreamBase
};
})();
-/*
+
+/*
Parser-Lib
Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.
@@ -951,7 +943,7 @@ 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 */
+/* Build time: 13-July-2011 04:35:28 */
(function(){
var EventTarget = parserlib.util.EventTarget,
TokenStreamBase = parserlib.util.TokenStreamBase,
@@ -985,7 +977,6 @@ var Colors = {
darkcyan :"#008b8b",
darkgoldenrod :"#b8860b",
darkgray :"#a9a9a9",
- darkgrey :"#a9a9a9",
darkgreen :"#006400",
darkkhaki :"#bdb76b",
darkmagenta :"#8b008b",
@@ -997,13 +988,11 @@ var Colors = {
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",
@@ -1014,7 +1003,6 @@ var Colors = {
gold :"#ffd700",
goldenrod :"#daa520",
gray :"#808080",
- grey :"#808080",
green :"#008000",
greenyellow :"#adff2f",
honeydew :"#f0fff0",
@@ -1031,7 +1019,6 @@ var Colors = {
lightcoral :"#f08080",
lightcyan :"#e0ffff",
lightgoldenrodyellow :"#fafad2",
- lightgray :"#d3d3d3",
lightgrey :"#d3d3d3",
lightgreen :"#90ee90",
lightpink :"#ffb6c1",
@@ -1039,7 +1026,6 @@ var Colors = {
lightseagreen :"#20b2aa",
lightskyblue :"#87cefa",
lightslategray :"#778899",
- lightslategrey :"#778899",
lightsteelblue :"#b0c4de",
lightyellow :"#ffffe0",
lime :"#00ff00",
@@ -1092,7 +1078,6 @@ var Colors = {
skyblue :"#87ceeb",
slateblue :"#6a5acd",
slategray :"#708090",
- slategrey :"#708090",
snow :"#fffafa",
springgreen :"#00ff7f",
steelblue :"#4682b4",
@@ -1106,52 +1091,21 @@ var Colors = {
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."
+ yellowgreen :"#9acd32"
};
-/*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 {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){
-
- SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE);
+
+ SyntaxUnit.call(this, text, line, col);
/**
* The type of modifier.
@@ -1159,7 +1113,7 @@ function Combinator(text, line, col){
* @property type
*/
this.type = "unknown";
-
+
//pretty simple
if (/^\s+$/.test(text)){
this.type = "descendant";
@@ -1176,7 +1130,183 @@ function Combinator(text, line, col){
Combinator.prototype = new SyntaxUnit();
Combinator.prototype.constructor = Combinator;
-/*global SyntaxUnit, Parser*/
+
+
+var Level1Properties = {
+
+ "background": 1,
+ "background-attachment": 1,
+ "background-color": 1,
+ "background-image": 1,
+ "background-position": 1,
+ "background-repeat": 1,
+
+ "border": 1,
+ "border-bottom": 1,
+ "border-bottom-width": 1,
+ "border-color": 1,
+ "border-left": 1,
+ "border-left-width": 1,
+ "border-right": 1,
+ "border-right-width": 1,
+ "border-style": 1,
+ "border-top": 1,
+ "border-top-width": 1,
+ "border-width": 1,
+
+ "clear": 1,
+ "color": 1,
+ "display": 1,
+ "float": 1,
+
+ "font": 1,
+ "font-family": 1,
+ "font-size": 1,
+ "font-style": 1,
+ "font-variant": 1,
+ "font-weight": 1,
+
+ "height": 1,
+ "letter-spacing": 1,
+ "line-height": 1,
+
+ "list-style": 1,
+ "list-style-image": 1,
+ "list-style-position": 1,
+ "list-style-type": 1,
+
+ "margin": 1,
+ "margin-bottom": 1,
+ "margin-left": 1,
+ "margin-right": 1,
+ "margin-top": 1,
+
+ "padding": 1,
+ "padding-bottom": 1,
+ "padding-left": 1,
+ "padding-right": 1,
+ "padding-top": 1,
+
+ "text-align": 1,
+ "text-decoration": 1,
+ "text-indent": 1,
+ "text-transform": 1,
+
+ "vertical-align": 1,
+ "white-space": 1,
+ "width": 1,
+ "word-spacing": 1
+
+};
+
+var Level2Properties = {
+
+ //Aural
+ "azimuth": 1,
+ "cue-after": 1,
+ "cue-before": 1,
+ "cue": 1,
+ "elevation": 1,
+ "pause-after": 1,
+ "pause-before": 1,
+ "pause": 1,
+ "pitch-range": 1,
+ "pitch": 1,
+ "play-during": 1,
+ "richness": 1,
+ "speak-header": 1,
+ "speak-numeral": 1,
+ "speak-punctuation": 1,
+ "speak": 1,
+ "speech-rate": 1,
+ "stress": 1,
+ "voice-family": 1,
+ "volume": 1,
+
+ //Paged
+ "orphans": 1,
+ "page-break-after": 1,
+ "page-break-before": 1,
+ "page-break-inside": 1,
+ "widows": 1,
+
+ //Interactive
+ "cursor": 1,
+ "outline-color": 1,
+ "outline-style": 1,
+ "outline-width": 1,
+ "outline": 1,
+
+ //Visual
+ "background-attachment": 1,
+ "background-color": 1,
+ "background-image": 1,
+ "background-position": 1,
+ "background-repeat": 1,
+ "background": 1,
+ "border-collapse": 1,
+ "border-color": 1,
+ "border-spacing": 1,
+ "border-style": 1,
+ "border-top": 1,
+ "border-top-color": 1,
+ "border-top-style": 1,
+ "border-top-width": 1,
+ "border-width": 1,
+ "border": 1,
+ "bottom": 1,
+ "caption-side": 1,
+ "clear": 1,
+ "clip": 1,
+ "color": 1,
+ "content": 1,
+ "counter-increment": 1,
+ "counter-reset": 1,
+ "direction": 1,
+ "display": 1,
+ "empty-cells": 1,
+ "float": 1,
+ "font-family": 1,
+ "font-size": 1,
+ "font-style": 1,
+ "font-variant": 1,
+ "font-weight": 1,
+ "font": 1,
+ "height": 1,
+ "left": 1,
+ "letter-spacing": 1,
+ "line-height": 1,
+ "list-style-image": 1,
+ "list-style-position": 1,
+ "list-style-type": 1,
+ "list-style": 1,
+ "margin-right": 1,
+ "margin-top": 1,
+ "margin": 1,
+ "max-height": 1,
+ "max-width": 1,
+ "min-height": 1,
+ "min-width": 1,
+ "overflow": 1,
+ "padding-top": 1,
+ "padding": 1,
+ "position": 1,
+ "quotes": 1,
+ "right": 1,
+ "table-layout": 1,
+ "text-align": 1,
+ "text-decoration": 1,
+ "text-indent": 1,
+ "text-transform": 1,
+ "top": 1,
+ "unicode-bidi": 1,
+ "vertical-align": 1,
+ "visibility": 1,
+ "white-space": 1,
+ "width": 1,
+ "word-spacing": 1,
+ "z-index": 1
+};
/**
* Represents a media feature, such as max-width:500.
* @namespace parserlib.css
@@ -1187,8 +1317,8 @@ Combinator.prototype.constructor = Combinator;
* @param {SyntaxUnit} value The value of the feature or null if none.
*/
function MediaFeature(name, value){
-
- SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE);
+
+ SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol);
/**
* The name of the media feature
@@ -1208,7 +1338,7 @@ function MediaFeature(name, value){
MediaFeature.prototype = new SyntaxUnit();
MediaFeature.prototype.constructor = MediaFeature;
-/*global SyntaxUnit, Parser*/
+
/**
* Represents an individual media query.
* @namespace parserlib.css
@@ -1222,8 +1352,8 @@ MediaFeature.prototype.constructor = MediaFeature;
* @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);
+
+ SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType + " " : "") + features.join(" and "), line, col);
/**
* The media modifier ("not" or "only")
@@ -1237,8 +1367,8 @@ function MediaQuery(modifier, mediaType, features, line, col){
* @type String
* @property mediaType
*/
- this.mediaType = mediaType;
-
+ this.mediaType = mediaType;
+
/**
* The parts that make up the selector.
* @type Array
@@ -1251,9 +1381,6 @@ function MediaQuery(modifier, mediaType, features, line, col){
MediaQuery.prototype = new SyntaxUnit();
MediaQuery.prototype.constructor = MediaQuery;
-/*global Tokens, TokenStream, SyntaxError, Properties, Validation, ValidationError, SyntaxUnit,
- PropertyValue, PropertyValuePart, SelectorPart, SelectorSubPart, Selector,
- PropertyName, Combinator, MediaFeature, MediaQuery, EventTarget */
/**
* A CSS3 parser.
@@ -1278,45 +1405,21 @@ function Parser(options){
this._tokenStream = null;
}
-//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;
-
Parser.prototype = function(){
var proto = new EventTarget(), //new prototype
prop,
additions = {
-
+
//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,
-
+
//-----------------------------------------------------------------
// Grammar
//-----------------------------------------------------------------
-
+
_stylesheet: function(){
-
+
/*
* stylesheet
* : [ CHARSET_SYM S* STRING S* ';' ]?
@@ -1324,19 +1427,18 @@ Parser.prototype = function(){
* [ namespace [S|CDO|CDC]* ]*
* [ [ ruleset | media | page | font_face | keyframes ] [S|CDO|CDC]* ]*
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
charset = null,
- count,
token,
tt;
-
+
this.fire("startstylesheet");
-
+
//try to read character set
this._charset();
-
+
this._skipCruft();
//try to read imports - may be more than one
@@ -1344,77 +1446,44 @@ Parser.prototype = function(){
this._import();
this._skipCruft();
}
-
+
//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();
-
+
//try to read the rest
while(tt > Tokens.EOF){
-
+
try {
-
+
switch(tt){
case Tokens.MEDIA_SYM:
this._media();
this._skipCruft();
break;
case Tokens.PAGE_SYM:
- this._page();
+ this._page();
this._skipCruft();
- break;
+ break;
case Tokens.FONT_FACE_SYM:
- this._font_face();
+ this._font_face();
this._skipCruft();
- break;
+ break;
case Tokens.KEYFRAMES_SYM:
- this._keyframes();
+ 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){
-
- //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
- });
-
- //skip braces
- count=0;
- while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){
- count++; //keep track of nesting depth
- }
-
- 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;
+ break;
case Tokens.S:
this._readWhitespace();
break;
- default:
+ default:
if(!this._ruleset()){
-
+
//error handling for known issues
switch(tt){
case Tokens.CHARSET_SYM:
@@ -1433,7 +1502,7 @@ Parser.prototype = function(){
tokenStream.get(); //get the last token
this._unexpectedToken(tokenStream.token());
}
-
+
}
}
} catch(ex) {
@@ -1444,84 +1513,84 @@ Parser.prototype = function(){
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;
-
+
if (tokenStream.match(Tokens.CHARSET_SYM)){
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
+
this._readWhitespace();
tokenStream.mustMatch(Tokens.STRING);
-
+
token = tokenStream.token();
charset = token.value;
-
+
this._readWhitespace();
tokenStream.mustMatch(Tokens.SEMICOLON);
-
+
if (emit !== false){
- this.fire({
+ this.fire({
type: "charset",
charset:charset,
line: line,
col: col
});
}
- }
+ }
},
-
+
_import: function(emit){
/*
* import
* : IMPORT_SYM S*
* [STRING|URI] S* media_query_list? ';' 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");
+ 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();
-
+
if (emit !== false){
this.fire({
type: "import",
@@ -1531,47 +1600,47 @@ Parser.prototype = function(){
col: importToken.startCol
});
}
-
+
},
-
+
_namespace: function(emit){
/*
* namespace
* : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
- */
-
+ */
+
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();
-
+
//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();
}
-
+
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");
+ uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");
this._readWhitespace();
//must end with a semicolon
tokenStream.mustMatch(Tokens.SEMICOLON);
this._readWhitespace();
-
+
if (emit !== false){
this.fire({
type: "namespace",
@@ -1581,9 +1650,9 @@ Parser.prototype = function(){
col: col
});
}
-
- },
-
+
+ },
+
_media: function(){
/*
* media
@@ -1594,49 +1663,45 @@ Parser.prototype = function(){
line,
col,
mediaList;// = [];
-
+
//look for @media
tokenStream.mustMatch(Tokens.MEDIA_SYM);
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
- this._readWhitespace();
+
+ this._readWhitespace();
mediaList = this._media_query_list();
tokenStream.mustMatch(Tokens.LBRACE);
this._readWhitespace();
-
+
this.fire({
type: "startmedia",
media: mediaList,
line: line,
col: col
});
-
+
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;
- }
+ }
}
-
+
tokenStream.mustMatch(Tokens.RBRACE);
this._readWhitespace();
-
+
this.fire({
type: "endmedia",
media: mediaList,
line: line,
col: col
});
- },
-
+ },
+
//CSS3 Media Queries
_media_query_list: function(){
@@ -1647,26 +1712,26 @@ Parser.prototype = function(){
*/
var tokenStream = this._tokenStream,
mediaList = [];
-
-
+
+
this._readWhitespace();
-
+
if (tokenStream.peek() == Tokens.IDENT || tokenStream.peek() == Tokens.LPAREN){
mediaList.push(this._media_query());
}
-
+
while(tokenStream.match(Tokens.COMMA)){
this._readWhitespace();
mediaList.push(this._media_query());
}
-
+
return mediaList;
},
-
+
/*
* Note: "expression" in the grammar maps to the _media_expression
* method.
-
+
*/
_media_query: function(){
/*
@@ -1680,10 +1745,10 @@ Parser.prototype = function(){
ident = null,
token = null,
expressions = [];
-
+
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();
@@ -1692,9 +1757,9 @@ Parser.prototype = function(){
token = tokenStream.token();
}
}
-
+
this._readWhitespace();
-
+
if (tokenStream.peek() == Tokens.IDENT){
type = this._media_type();
if (token === null){
@@ -1705,17 +1770,17 @@ Parser.prototype = function(){
token = tokenStream.LT(1);
}
expressions.push(this._media_expression());
- }
-
+ }
+
if (type === null && expressions.length === 0){
return null;
- } else {
+ } else {
this._readWhitespace();
while (tokenStream.match(Tokens.IDENT)){
if (tokenStream.token().value.toLowerCase() != "and"){
this._unexpectedToken(tokenStream.token());
}
-
+
this._readWhitespace();
expressions.push(this._media_expression());
}
@@ -1731,7 +1796,7 @@ Parser.prototype = function(){
* : IDENT
* ;
*/
- return this._media_feature();
+ return this._media_feature();
},
/**
@@ -1752,22 +1817,22 @@ Parser.prototype = function(){
feature = null,
token,
expression = null;
-
+
tokenStream.mustMatch(Tokens.LPAREN);
-
+
feature = this._media_feature();
this._readWhitespace();
-
+
if (tokenStream.match(Tokens.COLON)){
this._readWhitespace();
token = tokenStream.LT(1);
expression = this._expression();
}
-
+
tokenStream.mustMatch(Tokens.RPAREN);
this._readWhitespace();
- return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null));
+ return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null));
},
//CSS3 Media Queries
@@ -1778,33 +1843,33 @@ Parser.prototype = function(){
* ;
*/
var tokenStream = this._tokenStream;
-
+
tokenStream.mustMatch(Tokens.IDENT);
-
- return SyntaxUnit.fromToken(tokenStream.token());
+
+ return SyntaxUnit.fromToken(tokenStream.token());
},
-
+
//CSS3 Paged Media
_page: function(){
/*
* page:
- * PAGE_SYM S* IDENT? pseudo_page? S*
+ * PAGE_SYM S* IDENT? pseudo_page? S*
* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*
* ;
- */
+ */
var tokenStream = this._tokenStream,
line,
col,
identifier = null,
pseudoPage = null;
-
+
//look for @page
tokenStream.mustMatch(Tokens.PAGE_SYM);
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
+
this._readWhitespace();
-
+
if (tokenStream.match(Tokens.IDENT)){
identifier = tokenStream.token().value;
@@ -1812,35 +1877,35 @@ Parser.prototype = function(){
if (identifier.toLowerCase() === "auto"){
this._unexpectedToken(tokenStream.token());
}
- }
-
+ }
+
//see if there's a colon upcoming
if (tokenStream.peek() == Tokens.COLON){
pseudoPage = this._pseudo_page();
}
-
+
this._readWhitespace();
-
+
this.fire({
type: "startpage",
id: identifier,
pseudo: pseudoPage,
line: line,
col: col
- });
-
- this._readDeclarations(true, true);
+ });
+ this._readDeclarations(true, true);
+
this.fire({
type: "endpage",
id: identifier,
pseudo: pseudoPage,
line: line,
col: col
- });
-
+ });
+
},
-
+
//CSS3 Paged Media
_margin: function(){
/*
@@ -1856,14 +1921,14 @@ Parser.prototype = function(){
if (marginSym){
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
+
this.fire({
type: "startpagemargin",
margin: marginSym,
line: line,
col: col
- });
-
+ });
+
this._readDeclarations(true);
this.fire({
@@ -1871,7 +1936,7 @@ Parser.prototype = function(){
margin: marginSym,
line: line,
col: col
- });
+ });
return true;
} else {
return false;
@@ -1880,17 +1945,17 @@ Parser.prototype = function(){
//CSS3 Paged Media
_margin_sym: function(){
-
+
/*
* margin_sym :
- * TOPLEFTCORNER_SYM |
- * TOPLEFT_SYM |
- * TOPCENTER_SYM |
- * TOPRIGHT_SYM |
+ * TOPLEFTCORNER_SYM |
+ * TOPLEFT_SYM |
+ * TOPCENTER_SYM |
+ * TOPRIGHT_SYM |
* TOPRIGHTCORNER_SYM |
- * BOTTOMLEFTCORNER_SYM |
- * BOTTOMLEFT_SYM |
- * BOTTOMCENTER_SYM |
+ * BOTTOMLEFTCORNER_SYM |
+ * BOTTOMLEFT_SYM |
+ * BOTTOMCENTER_SYM |
* BOTTOMRIGHT_SYM |
* BOTTOMRIGHTCORNER_SYM |
* LEFTTOP_SYM |
@@ -1898,178 +1963,142 @@ Parser.prototype = function(){
* LEFTBOTTOM_SYM |
* RIGHTTOP_SYM |
* RIGHTMIDDLE_SYM |
- * RIGHTBOTTOM_SYM
+ * RIGHTBOTTOM_SYM
* ;
*/
-
+
var tokenStream = this._tokenStream;
-
+
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.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM,
Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM,
- Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_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());
+ return SyntaxUnit.fromToken(tokenStream.token());
} else {
return null;
}
-
+
},
-
+
_pseudo_page: function(){
/*
* pseudo_page
* : ':' IDENT
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream;
-
+
tokenStream.mustMatch(Tokens.COLON);
tokenStream.mustMatch(Tokens.IDENT);
-
+
//TODO: CSS3 Paged Media says only "left", "center", and "right" are allowed
-
+
return tokenStream.token().value;
},
-
+
_font_face: function(){
/*
* font_face
- * : FONT_FACE_SYM S*
+ * : FONT_FACE_SYM S*
* '{' S* declaration [ ';' S* declaration ]* '}' S*
* ;
- */
+ */
var tokenStream = this._tokenStream,
line,
col;
-
+
//look for @page
tokenStream.mustMatch(Tokens.FONT_FACE_SYM);
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
+
this._readWhitespace();
this.fire({
type: "startfontface",
line: line,
col: col
- });
-
+ });
+
this._readDeclarations(true);
-
+
this.fire({
type: "endfontface",
line: line,
col: col
- });
+ });
},
- _viewport: function(){
+ _operator: function(){
+
/*
- * viewport
- * : VIEWPORT_SYM S*
- * '{' S* declaration? [ ';' S* declaration? ]* '}' S*
- * ;
- */
- var tokenStream = this._tokenStream,
- line,
- col;
-
- tokenStream.mustMatch(Tokens.VIEWPORT_SYM);
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
-
- this._readWhitespace();
-
- this.fire({
- type: "startviewport",
- line: line,
- col: col
- });
-
- this._readDeclarations(true);
-
- this.fire({
- type: "endviewport",
- line: line,
- col: col
- });
-
- },
-
- _operator: function(inFunction){
-
- /*
- * operator (outside function)
+ * operator
* : '/' S* | ',' S* | /( empty )/
- * operator (inside function)
- * : '/' S* | '+' S* | '*' S* | '-' S* /( empty )/
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
token = null;
-
- if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) ||
- (inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))){
+
+ if (tokenStream.match([Tokens.SLASH, Tokens.COMMA])){
token = tokenStream.token();
this._readWhitespace();
- }
+ }
return token ? PropertyValuePart.fromToken(token) : null;
-
+
},
-
+
_combinator: function(){
-
+
/*
* combinator
* : PLUS S* | GREATER S* | TILDE S* | S+
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
value = null,
token;
-
- if(tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])){
+
+ 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;
},
-
+
_unary_operator: function(){
-
+
/*
* unary_operator
* : '-' | '+'
* ;
*/
-
+
var tokenStream = this._tokenStream;
-
+
if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){
return tokenStream.token().value;
} else {
return null;
- }
+ }
},
-
+
_property: function(){
-
+
/*
* property
* : IDENT S*
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream,
value = null,
hack = null,
@@ -2077,7 +2106,7 @@ Parser.prototype = function(){
token,
line,
col;
-
+
//check for star hack - throws error if not allowed
if (tokenStream.peek() == Tokens.STAR && this.options.starHack){
tokenStream.get();
@@ -2086,33 +2115,33 @@ Parser.prototype = function(){
line = token.startLine;
col = token.startCol;
}
-
+
if(tokenStream.match(Tokens.IDENT)){
token = tokenStream.token();
tokenValue = token.value;
-
+
//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);
}
-
+
value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol));
this._readWhitespace();
}
-
+
return value;
},
-
+
//Augmented with CSS3 Selectors
_ruleset: function(){
/*
* ruleset
* : selectors_group
* '{' S* declaration? [ ';' S* declaration? ]* '}' S*
- * ;
- */
-
+ * ;
+ */
+
var tokenStream = this._tokenStream,
tt,
selectors;
@@ -2126,7 +2155,7 @@ Parser.prototype = function(){
selectors = this._selectors_group();
} catch (ex){
if (ex instanceof SyntaxError && !this.options.strict){
-
+
//fire error event
this.fire({
type: "error",
@@ -2134,8 +2163,8 @@ Parser.prototype = function(){
message: ex.message,
line: ex.line,
col: ex.col
- });
-
+ });
+
//skip over everything until closing brace
tt = tokenStream.advance([Tokens.RBRACE]);
if (tt == Tokens.RBRACE){
@@ -2143,57 +2172,57 @@ Parser.prototype = function(){
} 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){
-
+ if (selectors){
+
this.fire({
type: "startrule",
selectors: selectors,
line: selectors[0].line,
col: selectors[0].col
- });
-
- this._readDeclarations(true);
-
+ });
+
+ 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 ]*
* ;
- */
+ */
var tokenStream = this._tokenStream,
selectors = [],
selector;
-
+
selector = this._selector();
if (selector !== null){
-
+
selectors.push(selector);
while(tokenStream.match(Tokens.COMMA)){
this._readWhitespace();
@@ -2208,83 +2237,83 @@ Parser.prototype = function(){
return selectors.length ? selectors : null;
},
-
+
//CSS3 Selectors
_selector: function(){
/*
* selector
* : simple_selector_sequence [ combinator simple_selector_sequence ]*
- * ;
+ * ;
*/
-
+
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));
+ this._unexpectedToken(this.LT(1));
} else {
-
+
//nextSelector is an instance of SelectorPart
selector.push(nextSelector);
}
} else {
-
+
//if there's not whitespace, we're done
- if (this._readWhitespace()){
-
+ 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 (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 Selectors
_simple_selector_sequence: function(){
/*
@@ -2294,13 +2323,13 @@ Parser.prototype = function(){
* | [ HASH | class | attrib | pseudo | negation ]+
* ;
*/
-
+
var tokenStream = this._tokenStream,
-
+
//parts of a simple selector
elementName = null,
modifiers = [],
-
+
//complete selector text
selectorText= "",
@@ -2323,35 +2352,35 @@ Parser.prototype = function(){
found = false,
line,
col;
-
-
+
+
//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();
}
-
+
if (elementName !== null){
selectorText += elementName;
- }
-
+ }
+
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;
@@ -2361,17 +2390,17 @@ Parser.prototype = function(){
} else {
i = 0;
modifiers.push(component);
- selectorText += component.toString();
+ selectorText += component.toString();
component = null;
}
}
-
+
return selectorText !== "" ?
new SelectorPart(elementName, modifiers, selectorText, line, col) :
null;
- },
-
+ },
+
//CSS3 Selectors
_type_selector: function(){
/*
@@ -2379,12 +2408,12 @@ Parser.prototype = function(){
* : [ namespace_prefix ]? element_name
* ;
*/
-
+
var tokenStream = this._tokenStream,
ns = this._namespace_prefix(),
elementName = this._element_name();
-
- if (!elementName){
+
+ if (!elementName){
/*
* Need to back out the namespace that was read due to both
* type_selector and universal reading namespace_prefix
@@ -2397,9 +2426,9 @@ Parser.prototype = function(){
tokenStream.unget();
}
}
-
+
return null;
- } else {
+ } else {
if (ns){
elementName.text = ns + elementName.text;
elementName.col -= ns.length;
@@ -2407,97 +2436,97 @@ Parser.prototype = function(){
return elementName;
}
},
-
+
//CSS3 Selectors
_class: function(){
/*
* class
* : '.' IDENT
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
token;
-
+
if (tokenStream.match(Tokens.DOT)){
- tokenStream.mustMatch(Tokens.IDENT);
+ tokenStream.mustMatch(Tokens.IDENT);
token = tokenStream.token();
- return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1);
+ return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1);
} else {
return null;
}
-
+
},
-
+
//CSS3 Selectors
_element_name: function(){
/*
* element_name
* : IDENT
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
token;
-
+
if (tokenStream.match(Tokens.IDENT)){
token = tokenStream.token();
- return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol);
-
+ return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol);
+
} else {
return null;
}
},
-
+
//CSS3 Selectors
_namespace_prefix: function(){
- /*
+ /*
* namespace_prefix
* : [ IDENT | '*' ]? '|'
* ;
*/
var tokenStream = this._tokenStream,
value = "";
-
+
//verify that this is a namespace prefix
if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){
-
+
if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){
value += tokenStream.token().value;
}
-
+
tokenStream.mustMatch(Tokens.PIPE);
value += "|";
-
+
}
-
- return value.length ? value : null;
+
+ return value.length ? value : null;
},
-
+
//CSS3 Selectors
_universal: function(){
/*
* universal
* : [ namespace_prefix ]? '*'
- * ;
+ * ;
*/
var tokenStream = this._tokenStream,
value = "",
ns;
-
+
ns = this._namespace_prefix();
if(ns){
value += ns;
}
-
+
if(tokenStream.match(Tokens.STAR)){
value += "*";
}
-
+
return value.length ? value : null;
-
+
},
-
+
//CSS3 Selectors
_attrib: function(){
/*
@@ -2510,69 +2539,69 @@ Parser.prototype = function(){
* INCLUDES |
* DASHMATCH ] S* [ IDENT | STRING ] S*
* ]? ']'
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream,
value = null,
ns,
token;
-
+
if (tokenStream.match(Tokens.LBRACKET)){
token = tokenStream.token();
value = token.value;
value += this._readWhitespace();
-
+
ns = this._namespace_prefix();
-
+
if (ns){
value += ns;
}
-
+
tokenStream.mustMatch(Tokens.IDENT);
- value += tokenStream.token().value;
+ value += tokenStream.token().value;
value += this._readWhitespace();
-
+
if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH,
Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){
-
- value += tokenStream.token().value;
+
+ value += tokenStream.token().value;
value += this._readWhitespace();
-
+
tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
- value += tokenStream.token().value;
+ value += tokenStream.token().value;
value += this._readWhitespace();
}
-
+
tokenStream.mustMatch(Tokens.RBRACKET);
-
+
return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol);
} else {
return null;
}
},
-
+
//CSS3 Selectors
_pseudo: function(){
-
+
/*
* pseudo
* : ':' ':'? [ IDENT | functional_pseudo ]
- * ;
- */
-
+ * ;
+ */
+
var tokenStream = this._tokenStream,
pseudo = null,
colons = ":",
line,
col;
-
+
if (tokenStream.match(Tokens.COLON)){
-
+
if (tokenStream.match(Tokens.COLON)){
colons += ":";
}
-
+
if (tokenStream.match(Tokens.IDENT)){
pseudo = tokenStream.token().value;
line = tokenStream.token().startLine;
@@ -2582,26 +2611,26 @@ Parser.prototype = function(){
col = tokenStream.LT(1).startCol - colons.length;
pseudo = this._functional_pseudo();
}
-
+
if (pseudo){
pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col);
}
}
-
+
return pseudo;
},
-
+
//CSS3 Selectors
_functional_pseudo: function(){
/*
* functional_pseudo
* : FUNCTION S* expression ')'
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
value = null;
-
+
if(tokenStream.match(Tokens.FUNCTION)){
value = tokenStream.token().value;
value += this._readWhitespace();
@@ -2609,10 +2638,10 @@ Parser.prototype = function(){
tokenStream.mustMatch(Tokens.RPAREN);
value += ")";
}
-
+
return value;
},
-
+
//CSS3 Selectors
_expression: function(){
/*
@@ -2620,26 +2649,26 @@ Parser.prototype = function(){
* : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
* ;
*/
-
+
var tokenStream = this._tokenStream,
value = "";
-
+
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])){
-
+ Tokens.RESOLUTION])){
+
value += tokenStream.token().value;
- value += this._readWhitespace();
+ value += this._readWhitespace();
}
-
+
return value.length ? value : null;
-
+
},
//CSS3 Selectors
_negation: function(){
- /*
+ /*
* negation
* : NOT S* negation_arg S* ')'
* ;
@@ -2651,7 +2680,7 @@ Parser.prototype = function(){
value = "",
arg,
subpart = null;
-
+
if (tokenStream.match(Tokens.NOT)){
value = tokenStream.token().value;
line = tokenStream.token().startLine;
@@ -2662,22 +2691,22 @@ Parser.prototype = function(){
value += this._readWhitespace();
tokenStream.match(Tokens.RPAREN);
value += tokenStream.token().value;
-
+
subpart = new SelectorSubPart(value, "not", line, col);
subpart.args.push(arg);
}
-
+
return subpart;
},
-
+
//CSS3 Selectors
- _negation_arg: function(){
+ _negation_arg: function(){
/*
* negation_arg
* : type_selector | universal | HASH | class | attrib | pseudo
- * ;
- */
-
+ * ;
+ */
+
var tokenStream = this._tokenStream,
args = [
this._type_selector,
@@ -2685,11 +2714,11 @@ Parser.prototype = function(){
function(){
return tokenStream.match(Tokens.HASH) ?
new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) :
- null;
+ null;
},
this._class,
this._attrib,
- this._pseudo
+ this._pseudo
],
arg = null,
i = 0,
@@ -2698,132 +2727,110 @@ Parser.prototype = function(){
line,
col,
part;
-
+
line = tokenStream.LT(1).startLine;
col = tokenStream.LT(1).startCol;
-
+
while(i < len && arg === null){
-
+
arg = args[i].call(this);
i++;
}
-
+
//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 part;
+
+ return part;
},
-
+
_declaration: function(){
-
+
/*
* declaration
* : property ':' S* expr prio?
* | /( empty )/
- * ;
- */
-
+ * ;
+ */
+
var tokenStream = this._tokenStream,
property = null,
expr = null,
- prio = null,
- error = null,
- invalid = null,
- propertyName= "";
-
+ prio = null;
+
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 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 == "_") {
-
- propertyName = property.text;
- }
-
- try {
- this._validateProperty(propertyName, expr);
- } catch (ex) {
- invalid = ex;
- }
-
+
this.fire({
type: "property",
property: property,
value: expr,
important: prio,
line: property.line,
- col: property.col,
- invalid: invalid
- });
-
+ col: property.col
+ });
+
return true;
} else {
return false;
}
},
-
+
_prio: function(){
/*
* prio
* : IMPORTANT_SYM S*
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream,
result = tokenStream.match(Tokens.IMPORTANT_SYM);
-
+
this._readWhitespace();
return result;
},
-
- _expr: function(inFunction){
+
+ _expr: function(){
/*
* expr
* : term [ operator term ]*
* ;
*/
-
+
var tokenStream = this._tokenStream,
values = [],
//valueParts = [],
value = null,
operator = null;
-
- value = this._term(inFunction);
+
+ value = this._term();
if (value !== null){
-
+
values.push(value);
-
+
do {
- operator = this._operator(inFunction);
-
+ operator = this._operator();
+
//if there's an operator, keep building up the value parts
if (operator){
values.push(operator);
@@ -2832,9 +2839,9 @@ Parser.prototype = function(){
values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));
valueParts = [];
}*/
-
- value = this._term(inFunction);
-
+
+ value = this._term();
+
if (value === null){
break;
} else {
@@ -2842,17 +2849,17 @@ Parser.prototype = function(){
}
} while(true);
}
-
+
//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;
+
+ return values.length > 0 ? new PropertyValue(values, values[0].startLine, values[0].startCol) : null;
},
-
- _term: function(inFunction){
-
+
+ _term: function(){
+
/*
* term
* : unary_operator?
@@ -2860,51 +2867,35 @@ Parser.prototype = function(){
* TIME S* | FREQ S* | function | ie_function ]
* | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor
* ;
- */
-
+ */
+
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;
- }
-
+ }
+
//exception for IE filters
if (tokenStream.peek() == Tokens.IE_FUNCTION && this.options.ieFilters){
-
+
value = this._ie_function();
if (unary === null){
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
}
-
- //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;
@@ -2912,20 +2903,20 @@ Parser.prototype = function(){
}
this._readWhitespace();
} else {
-
+
//see if it's a color
- token = this._hexcolor();
- if (token === null){
-
+ value = this._hexcolor();
+ if (value === 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.
@@ -2941,115 +2932,81 @@ Parser.prototype = function(){
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;
- }
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+ }
}
-
- }
-
+
+ }
+
return value !== null ?
new PropertyValuePart(unary !== null ? unary + value : value, line, col) :
null;
-
+
},
-
+
_function: function(){
-
+
/*
* function
* : FUNCTION S* expr ')' S*
* ;
*/
-
+
var tokenStream = this._tokenStream,
functionText = null,
- expr = null,
- lt;
-
+ expr = null;
+
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 {
-
- if (this._readWhitespace()){
- functionText += tokenStream.token().value;
- }
-
- //might be second time in the loop
- if (tokenStream.LA(0) == Tokens.COMMA){
- functionText += tokenStream.token().value;
- }
-
- tokenStream.match(Tokens.IDENT);
- functionText += tokenStream.token().value;
-
- tokenStream.match(Tokens.EQUALS);
- functionText += 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]));
- }
-
- //END: Horrible Hack
-
- tokenStream.match(Tokens.RPAREN);
- functionText += ")";
+ expr = this._expr();
+
+ tokenStream.match(Tokens.RPAREN);
+ functionText += expr + ")";
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;
-
+
do {
-
+
if (this._readWhitespace()){
functionText += tokenStream.token().value;
}
-
+
//might be second time in the loop
if (tokenStream.LA(0) == Tokens.COMMA){
functionText += tokenStream.token().value;
}
-
+
tokenStream.match(Tokens.IDENT);
functionText += tokenStream.token().value;
-
+
tokenStream.match(Tokens.EQUALS);
functionText += tokenStream.token().value;
-
+
//functionText += this._term();
lt = tokenStream.peek();
while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){
@@ -3057,16 +3014,16 @@ Parser.prototype = function(){
functionText += tokenStream.token().value;
lt = tokenStream.peek();
}
- } while(tokenStream.match([Tokens.COMMA, Tokens.S]));
-
- tokenStream.match(Tokens.RPAREN);
+ } while(tokenStream.match([Tokens.COMMA, Tokens.S]));
+
+ tokenStream.match(Tokens.RPAREN);
functionText += ")";
this._readWhitespace();
- }
-
+ }
+
return functionText;
- },
-
+ },
+
_hexcolor: function(){
/*
* There is a constraint on the color that it must
@@ -3077,15 +3034,15 @@ Parser.prototype = function(){
* : HASH S*
* ;
*/
-
+
var tokenStream = this._tokenStream,
- token = null,
- color;
-
+ token,
+ color = null;
+
if(tokenStream.match(Tokens.HASH)){
-
+
//need to do some validation here
-
+
token = tokenStream.token();
color = token.value;
if (!/#[a-f0-9]{3,6}/i.test(color)){
@@ -3093,16 +3050,16 @@ Parser.prototype = function(){
}
this._readWhitespace();
}
-
- return token;
+
+ return color;
},
-
+
//-----------------------------------------------------------------
// Animations methods
//-----------------------------------------------------------------
-
+
_keyframes: function(){
-
+
/*
* keyframes:
* : KEYFRAMES_SYM S* keyframe_name S* '{' S* keyframe_rule* '}' {
@@ -3111,54 +3068,46 @@ Parser.prototype = function(){
var tokenStream = this._tokenStream,
token,
tt,
- name,
- prefix = "";
-
+ name;
+
tokenStream.mustMatch(Tokens.KEYFRAMES_SYM);
- token = tokenStream.token();
- if (/^@\-([^\-]+)\-/.test(token.value)) {
- prefix = RegExp.$1;
- }
-
this._readWhitespace();
name = this._keyframe_name();
-
+
this._readWhitespace();
tokenStream.mustMatch(Tokens.LBRACE);
-
+
this.fire({
type: "startkeyframes",
name: name,
- prefix: prefix,
- line: token.startLine,
- col: token.startCol
- });
-
+ line: name.line,
+ col: name.col
+ });
+
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
- });
-
+ line: name.line,
+ col: name.col
+ });
+
this._readWhitespace();
- tokenStream.mustMatch(Tokens.RBRACE);
-
+ tokenStream.mustMatch(Tokens.RBRACE);
+
},
-
+
_keyframe_name: function(){
-
+
/*
* keyframe_name:
* : IDENT
@@ -3169,41 +3118,41 @@ Parser.prototype = function(){
token;
tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
- return SyntaxUnit.fromToken(tokenStream.token());
+ return SyntaxUnit.fromToken(tokenStream.token());
},
-
+
_keyframe_rule: function(){
-
+
/*
* keyframe_rule:
- * : key_list S*
+ * : 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._readDeclarations(true);
+
this.fire({
type: "endkeyframerule",
keys: keyList,
line: keyList[0].line,
col: keyList[0].col
- });
-
+ });
+
},
-
+
_key_list: function(){
-
+
/*
* key_list:
* : key [ S* ',' S* key]*
@@ -3213,12 +3162,12 @@ Parser.prototype = function(){
token,
key,
keyList = [];
-
+
//must be least one key
keyList.push(this._key());
-
+
this._readWhitespace();
-
+
while(tokenStream.match(Tokens.COMMA)){
this._readWhitespace();
keyList.push(this._key());
@@ -3227,7 +3176,7 @@ Parser.prototype = function(){
return keyList;
},
-
+
_key: function(){
/*
* There is a restriction that IDENT can be only "from" or "to".
@@ -3237,30 +3186,30 @@ Parser.prototype = function(){
* | IDENT
* ;
*/
-
+
var tokenStream = this._tokenStream,
token;
-
+
if (tokenStream.match(Tokens.PERCENTAGE)){
return SyntaxUnit.fromToken(tokenStream.token());
} else if (tokenStream.match(Tokens.IDENT)){
- token = tokenStream.token();
-
+ token = tokenStream.token();
+
if (/from|to/i.test(token.value)){
return SyntaxUnit.fromToken(token);
}
-
+
tokenStream.unget();
}
-
+
//if it gets here, there wasn't a valid token, so time to explode
this._unexpectedToken(tokenStream.LT(1));
},
-
+
//-----------------------------------------------------------------
// Helper methods
//-----------------------------------------------------------------
-
+
/**
* Not part of CSS grammar, but useful for skipping over
* combination of white space and HTML-style comments.
@@ -3293,26 +3242,26 @@ Parser.prototype = function(){
* 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.
+ * A semicolon is only necessary following a delcaration is there's another declaration
+ * or margin afterwards.
*/
var tokenStream = this._tokenStream,
tt;
-
+
this._readWhitespace();
-
+
if (checkStart){
- tokenStream.mustMatch(Tokens.LBRACE);
+ tokenStream.mustMatch(Tokens.LBRACE);
}
-
+
this._readWhitespace();
try {
-
+
while(true){
-
- if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())){
+
+ if (readMargins && this._margin()){
//noop
} else if (this._declaration()){
if (!tokenStream.match(Tokens.SEMICOLON)){
@@ -3321,19 +3270,19 @@ Parser.prototype = function(){
} else {
break;
}
-
+
//if ((!this._margin() && !this._declaration()) || !tokenStream.match(Tokens.SEMICOLON)){
// break;
//}
this._readWhitespace();
}
-
+
tokenStream.mustMatch(Tokens.RBRACE);
this._readWhitespace();
-
+
} catch (ex) {
if (ex instanceof SyntaxError && !this.options.strict){
-
+
//fire error event
this.fire({
type: "error",
@@ -3341,27 +3290,28 @@ Parser.prototype = function(){
message: ex.message,
line: ex.line,
col: ex.col
- });
-
+ });
+
//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.RBRACE){
+ } else 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;
}
- }
-
- },
-
+ }
+
+ },
+
/**
* 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
@@ -3372,17 +3322,17 @@ Parser.prototype = function(){
* @private
*/
_readWhitespace: function(){
-
+
var tokenStream = this._tokenStream,
ws = "";
-
+
while(tokenStream.match(Tokens.S)){
ws += tokenStream.token().value;
}
-
+
return ws;
},
-
+
/**
* Throws an error when an unexpected token is found.
@@ -3394,7 +3344,7 @@ Parser.prototype = function(){
_unexpectedToken: function(token){
throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
},
-
+
/**
* Helper method used for parsing subparts of a style sheet.
* @return {void}
@@ -3404,64 +3354,57 @@ Parser.prototype = function(){
_verifyEnd: function(){
if (this._tokenStream.LA(1) != Tokens.EOF){
this._unexpectedToken(this._tokenStream.LT(1));
- }
+ }
},
-
- //-----------------------------------------------------------------
- // Validation methods
- //-----------------------------------------------------------------
- _validateProperty: function(property, value){
- Validation.validate(property, value);
- },
-
+
//-----------------------------------------------------------------
// Parsing methods
//-----------------------------------------------------------------
-
- parse: function(input){
+
+ parse: function(input){
this._tokenStream = new TokenStream(input, Tokens);
this._stylesheet();
},
-
+
parseStyleSheet: function(input){
//just passthrough
return this.parse(input);
},
-
+
parseMediaQuery: function(input){
this._tokenStream = new TokenStream(input, Tokens);
var result = this._media_query();
-
+
//if there's anything more, then it's an invalid selector
this._verifyEnd();
-
+
//otherwise return result
- return result;
+ return result;
},
-
+
/**
* 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();
-
+
var result = this._expr();
-
+
//okay to have a trailing white space
this._readWhitespace();
-
+
//if there's anything more, then it's an invalid selector
this._verifyEnd();
-
+
//otherwise return result
return result;
},
-
+
/**
* Parses a complete CSS rule, including selectors and
* properties.
@@ -3471,22 +3414,22 @@ Parser.prototype = function(){
*/
parseRule: function(input){
this._tokenStream = new TokenStream(input, Tokens);
-
+
//skip any leading white space
this._readWhitespace();
-
+
var result = this._ruleset();
-
+
//skip any trailing white space
this._readWhitespace();
//if there's anything more, then it's an invalid selector
this._verifyEnd();
-
+
//otherwise return result
- return result;
+ return result;
},
-
+
/**
* Parses a single CSS selector (no comma)
* @param {String} input The text to parse as a CSS selector.
@@ -3495,45 +3438,31 @@ Parser.prototype = function(){
* @method parseSelector
*/
parseSelector: function(input){
-
+
this._tokenStream = new TokenStream(input, Tokens);
-
+
//skip any leading white space
this._readWhitespace();
-
+
var result = this._selector();
-
+
//skip any trailing white space
this._readWhitespace();
//if there's anything more, then it's an invalid selector
this._verifyEnd();
-
+
//otherwise return result
return result;
- },
-
- /**
- * 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 parseStyleAttribute
- */
- parseStyleAttribute: function(input){
- input += "}"; // for error recovery in _readDeclarations()
- this._tokenStream = new TokenStream(input, Tokens);
- this._readDeclarations();
}
+
};
-
+
//copy over onto prototype
for (prop in additions){
- if (additions.hasOwnProperty(prop)){
- proto[prop] = additions[prop];
- }
- }
-
+ proto[prop] = additions[prop];
+ }
+
return proto;
}();
@@ -3544,549 +3473,20 @@ nth
['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
;
*/
-/*global Validation, ValidationTypes, ValidationError*/
-var Properties = {
-
- //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",
- "-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" : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
- "animation" : 1,
- "animation-delay" : { multi: "