Swagger2-0.89/000755 000765 000024 00000000000 13056113272 014302 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/.perltidyrc000644 000765 000024 00000000714 12757311624 016476 0ustar00jhthorsenstaff000000 000000 -pbp # Start with Perl Best Practices -w # Show all warnings -iob # Ignore old breakpoints -l=100 # Characters per line -mbl=2 # No more than 2 blank lines -i=2 # Indentation is 2 columns -ci=2 # Continuation indentation is 2 columns -vt=0 # Less vertical tightness -pt=2 # High parenthesis tightness -bt=2 # High brace tightness -sbt=2 # High square bracket tightness -isbc # Don't indent comments without leading space Swagger2-0.89/.ship.conf000644 000765 000024 00000000470 12757311624 016203 0ustar00jhthorsenstaff000000 000000 # Generated by git-ship. See 'git-ship --man' for help or https://github.com/jhthorsen/app-git-ship class = App::git::ship::perl project_name = homepage = https://github.com/jhthorsen/swagger2 bugtracker = https://github.com/jhthorsen/swagger2/issues license = artistic_2 build_test_options = # Example: -l -j8 Swagger2-0.89/.travis.yml000644 000765 000024 00000000507 12757311624 016425 0ustar00jhthorsenstaff000000 000000 language: perl perl: - "5.20" - "5.16" - "5.10" env: - "HARNESS_OPTIONS=j6" install: - "cpanm -n Test::Pod Test::Pod::Coverage Data::Validate::Domain Data::Validate::IP YAML" - "cpanm -n https://github.com/jhthorsen/json-validator/archive/master.tar.gz" - "cpanm -n --installdeps ." notifications: email: false Swagger2-0.89/Changes000644 000765 000024 00000031310 13056113272 015573 0ustar00jhthorsenstaff000000 000000 Revision history for perl distribution Swagger2 0.89 2017-03-02T23:03:38+0100 - Deprecated for real 0.88 2016-12-24T14:35:48+0100 - Bump required JSON::Validator version to 0.90 - Add deprecation warning to Mojolicious::Plugin::Swagger2 - Deleted guides, since this dist will be deprecated 0.87 2016-12-11T11:39:23+0100 - Compatible with JSON::Validator 0.90 0.86 2016-09-19T18:55:09+0200 - Deprecated distribution 0.85 2016-08-09T12:48:13+0200 - Fix finding all $ref occurances in JSON::Validator #95 0.84 2016-08-08T10:04:28+0200 - Fix recurring requests with same path part #93 0.83 2016-07-02T15:03:38+0200 - Bump JSON::Validator dependency to 0.75 - Change JSON::Validator will pass on uploads as Mojo::Upload objects 0.82 2016-06-22T19:27:24+0200 - Deprecating Swagger2::SchemaValidator in favor of JSON::Validator::OpenAPI - Fix Swagger2::Client formData parameters #87 Contributor: A.J. Lucas 0.81 2016-06-10T19:29:45-0700 - Fix Swagger2::POD looping over "x-" HTTP methods - Change Swagger2::Client to set Content-Type on faked error responses #84 Contributor: A.J. Lucas 0.80 2016-06-07T15:29:56-0500 - Fix validating required "file" in formData - Add support for "discriminator" #72 0.79 2016-05-23T19:15:25+0200 - Fix collectionFormat "multi" 0.78 2016-05-19T18:39:42+0200 - Add EXPERIMENTAL .html and .pod handling for "spec_path" rendering 0.77 2016-04-12T08:32:56+0200 - Add Swagger2->find_operations() method - Add support for plain WebSocket object passed to ws() in swagger2-client.js - Add http() to swagger2-client.js - Add load() to swagger2-client.js - Change ws() to be a setter and getter in swagger2-client.js - Mark "swagger_route_added" as DEPRECATED - Remove fresh() and cache features from swagger2-client.js 0.76 2016-04-09T09:52:34+0200 - Fix new($file)->expand->validate #80 Contributors: Tina Müller and Daniel Böhmer - Add EXPERIMENTAL support for SWAGGER2_IO_LOGGING=debug - Documented different response types #78 #79 - Removed deprecated methods specification() and tree() 0.75 2016-02-22T09:02:43+0000 - Fix indentation of JSONSchemaSupport guide 0.74 2016-02-19T11:28:52+0000 - Add x-json-schema support Contributor: Martin Renvoize 0.73 2016-02-15T14:04:15+0100 - Fix "0" as placeholder value #74 Contributor: Le Garff Yoann 0.72 2016-02-12T11:30:05+0100 - Fix rendering Swagger spec cannot contain "id" and "x-mojo-xxx" - Fix rendering Swagger spec with requested host in response. - Made the code less confusing by removing the /o regex modifier #71 Contributor: Daniel Böhmer 0.71 2016-02-08T21:29:57+0100 - Bundle EXPERIMENTAL swagger2-client.js - Fix spelling error #70 Contributor: Lucas Kanashiro 0.70 2016-01-29T10:50:57+0100 - Documentation fixes Contributor: Bernhard Graf - Remove outdated warning #69 Contributor: Denny de la Haye 0.69 2016-01-14T22:01:15+0100 - Allow blocking Swagger2::Client requests to return on failure #67 0.68 2016-01-13T16:36:28+0100 - Can serve specification from basePath - Fix skipping tests on MSWin32 #66 Contributor: Paul Durden 0.67 2016-01-12T14:36:24+0100 - Add "basePath" to "Add route ..." debug message #64 - Can pass Swagger2->new to Swagger2::Client #63 - Fix new(url => Mojo::URL->new(...)); - Fix expand() will not clear url() 0.66 2015-12-29T11:52:06+0100 - Will not add non-existing input keys to $args #52 Contributor: Scott Wiersdorf - Use $c->match instead of $c->stash to get placeholder data - Add "From" to list of ignored words in SKIP_OP_RE #54 - Allow more complex method name detection from operationId #55 - Skipping editor test on Win32 #56 - Boolean in headers will be the strings "true" and "false" #58 0.65 2015-12-03T12:51:51+0100 - Swagger2::Client will generate both camel- and snake case methods - Swagger2::Client pass $err as a string to callback - Swagger2::Editor can save specification back to disk on POST 0.64 2015-11-28T08:18:45+0100 - YAML::Tiny is no longer supported by JSON::Validator - Bump JSON::Validator dependency to 0.63 0.63 2015-11-19T09:22:44+0100 - Add validation of output headers, fixes #41 - Add support for "readOnly" in object properties #49 0.62 2015-11-04T12:42:32+0000 - Trying to authorise release 0.61 2015-11-03T20:22:55+0000 - Fix handling of empty collectionFormat value - Fix handling of arrays in request body - Add validation for 204 No Content response 0.60 2015-10-14T23:25:14+0200 - Fix pass on $app to WebSocket controller - Fix support for "collectionFormat" for both "parameters" and "items" - Add support for "collectionFormat" "multi" 0.59 2015-10-11T13:22:31+0200 - Fix validating required body - Add resource to download full API spec - Add before_render hook to make sure we reply with JSON - Add EXPERIMENTAL dispatch_to_swagger() 0.58 2015-10-06T11:36:29+0200 - Add support for using operationId instead of x-mojo-controller #36 #37 - Add "swagger_route_added" event #27 - Remove "valid" from standard error structure since it was redundant - Documented how to include http://git.io/vcKD4 0.57 2015-09-30T11:48:22+0200 - Require JSON::Validator 0.56 for YAML validation - Add support for passing "coerce" to M::P::Swagger2::register() 0.56 2015-09-29T20:23:07+0200 - Add Mojolicious::Plugin::Swagger2 will validate spec on load 0.55 2015-09-27T16:53:08+0200 - Split Mojolicious::Plugin::Swagger2 into guides - Remove EXPERIMENTAL from "x-mojo-around-action" 0.54 2015-09-27T13:37:06+0200 - Compatible with JSON::Validator 0.54 - Compatible with Mojolicious 6.22 - Rename index.html.ep to list.html.ep in blog example #28 Contributor: Stephan Jauernick - Paths are sorted from the most specific to least specific #35 Contributor: Olli-Antti Kivilahti 0.53 2015-09-13T15:55:54+0200 - Add EXPERIMENTAL naming of swagger routes #27 - Add "swagger_operation_spec" to route defaults #30 - Allow x-mojo-around-action to be inherited #30 - Allow x-mojo-controller to be inherited - Swagger2::SchemaValidator is back because JSON::Validator cannot be Swagger specific 0.52 2015-09-13T10:53:14+0200 - Fix validate(): Need to expand, as well as depend on fixes in JSON::Validator - Will also log the operationId not implemented - Deprecated tree() in favor of api_spec() - Deprecated specification() 0.51 2015-09-03T12:22:20+0200 - Fix dumper() in Command::swagger2 - Add /editor to example blog application - Add slides for YAPC::EU 2015 t/blog/2015-yapc-eu-slides.pdf 0.50 2015-08-24T16:28:42+0200 - Should not use Swagger2::SchemaValidator #25 0.49 2015-08-23T15:16:09+0200 - Remove naming or routes to fix unique problem #23 0.48 2015-08-23T15:09:58+0200 - Core validation functionality is moved to JSON::Validator #25 0.47 2015-08-11T18:16:54+0200 - Add "swagger" as default stash() value 0.46 2015-08-11T16:35:04+0200 - Add support for giving an Swagger2 object to the plugin - Add support for "collectionFormat" (PARTIAL) #17 - Deprecated passing "controller" as argument to plugin - Remove warning about helpers defined twice #21 0.45 2015-08-11T14:32:05+0200 - Add support for x-mojo-around-action (EXPERIMENTAL) 0.44 2015-08-10T23:13:15+0200 - Updated schema.json https://twitter.com/SwaggerApi/status/627128354827862016 0.43 2015-07-14T17:36:07+0200 - Fix loading swagger spec from editor on Windows 0.42 2015-07-11T22:02:27+0200 - Fix parsing formData - Add support for no content in response 0.41 2015-07-11T12:25:55+0200 - Fix loading swagger spec from editor on Windows (failed) - Bump Mojolicous requirement to 6.00 0.40 2015-07-08T10:47:39+0200 - Fix "&Digest::MD5::md5_hex function called with reference argument" 0.39 2015-07-08T10:33:02+0200 - Allow negative integers in query string 0.38 2015-07-07T09:48:13+0200 - Will use "basePath" in root API route - Swagger2::Editor can load specifications over HTTP 0.37 2015-07-06T23:27:17+0200 - Bundle http://json-schema.org/draft-04/schema - Bundle http://swagger.io/v2/schema.json 0.36 2015-07-06T21:07:30+0200 - Remove EXPERIMENTAL from main Swagger2 module - Fix POST JSON data with Swagger2::Client - Updated swagger2 schema.json: Allow empty arrays for parameters - Add example blog app 0.35 2015-06-24T08:17:43+0200 - Add "mojo swagger2 client" command - Add EXPERIMENTAL "coerce" attribute to Swagger2::SchemaValidator 0.34 2015-06-22T10:13:44+0200 - Change order of YAML modules 0.33 2015-06-19T22:04:15+0200 - Add Swagger2::Client #8 - Fixed Mojolicious::Plugin::Swagger2 can use default values from schema #18 - Started deprecating "controller" as plugin config 0.32 2015-06-17T15:34:32+0200 - Allowing {n,no,false,off} as boolean false, #15 0.31 2015-05-13T12:42:39+0200 - Change required Mojolicious verision to 5.54 #14 0.30 2015-04-21T20:33:43+0200 - Fix failing test with YAML 1.15 #12 0.29 2015-04-09T09:52:40Z - Fix _schema_to_string_dispatch() can only be called with reference - Add support for raw text/binary data #6 - Add POD rendering of anyOf, allOf and oneOf #7 Contributor: Julian Maurice 0.28 2015-03-01T18:02:20Z - Allow setting specification_file when constructing Swagger2::Editor - Mojolicious::Routes::Route::bridge is DEPRECATED 0.27 2015-01-22T19:52:37Z - Fix validating "required" on a property - Fix validating output - Fix "path" in errors response when posting JSON or form data 0.26 2015-01-21T14:05:44Z - Fix validating body and form data - Add support for custom placeholder types 0.25 2015-01-20T12:26:23Z - Fix rendering "not implemented" - Fix parsing true/false in URL - Fix validating against empty rule set - Fix validating against "body" - Fix rendering "body" parameters in POD #5 - Documented custom route for Swagger2 Mojolicious plugin 0.24 2015-01-19T14:05:08Z - Add support for x-mojo-controller in swagger spec - HTTP method is not used in method name looked any more 0.23 2015-01-12T09:42:19Z - Fix scrolling to the right position after rendering POD - Fix loading ace.js from relative url - Will include description in POD, instead of just "required" - Remove editor shortcut CTRL+L - Add editor shortcut CTRL+F (find) - Can load API from same domain, using "#/path/to/api.json" fragment 0.22 2015-01-09T19:37:46Z - Allow "number" type when generating POD - Editor will also render "Table of contents" 0.21 2015-01-05T12:26:46Z - Fix order of headings in generated POD - Fix response codes are rendered with "=head4" - Made text in editor easier to read 0.20 2015-01-03T17:11:06Z - Fix loading $SWAGGER_API_FILE on Windows in Swagger2::Editor #4 Contributor: Andreas Koenig 0.19 2015-01-03T15:16:15Z - Move editor code from Mojolicious::Command::swagger2 to Swagger2::Editor 0.18 2015-01-03T14:16:31Z - Fix bodytest.t: YAML is not a required dependency 0.17 2015-01-03T10:30:29Z - Fix failing Windows test where the Mojo::URL path part is invalid 0.16 2015-01-02T12:44:33Z - Tried to fix failing Windows test where c:\path\to\spec is converted into a URL with scheme "c", #4 0.15 2014-12-19T13:26:24Z - Fix parse() will set tree() attribute - Allow editor to start without file 0.14 2014-12-18T16:06:02Z - Add both "summary" and "description" to POD - Add print styling for editor - Can resize editor area - Fix detecting yaml/json mode in editor 0.13 2014-12-18T14:06:26Z - Fix "not" logic in SchemaValidator 0.12 2014-12-16T11:30:34Z - Add missing Swagger2::POD::_schema_boolean_to_string() method - Add Swagger2::parse() method - Add "mojo swagger2 edit" command - Fix printing "Resource URL" when generating POD - Fix parameter references - Fix expanding bare $ref and $ref inside refs 0.11 2014-12-15T09:29:27Z - Add "mojo swagger2 pod" command - Add "mojo swagger2 perldoc" command - Add "mojo swagger2 validate" command - Change POD output to follow standard formatting 0.10 2014-12-15T07:27:51Z - Disable "int64" format test if Perl does not support 64 bit 0.09 2014-12-13T12:46:39Z - Fix adding parameter to route #1 - Fix "Resource URL" in generated POD - Add "Type" to "Parameters" POD table 0.08 2014-12-11T11:08:05Z - Change "floats" and "double" formats are not tested - Add support for "byte" format 0.07 2014-12-10T14:58:15Z - Fix test for negative integers - Add more formats: date, double, float, int32 and int64 0.06 2014-12-10T12:19:40Z - Fix t/jv-formats.t: Label not found for "last SKIP" 0.05 2014-12-09T22:01:31Z - Fix "Not an ARRAY reference at lib/Swagger2.pm line 356." 0.04 2014-12-09T21:02:43Z - Add "formats" to Swagger2::SchemaValidator 0.03 2014-12-09T15:36:04Z - Add Swagger2::validate() - Add Swagger 2.0 schema - Fix circular $ref when expanding a document - Rewrote Swagger2::SchemaValidator to support draft 4 0.02 2014-12-05T10:01:34Z - Add Swagger2::SchemaValidator - Add Swagger2::expand() - Add Mojolicious::Plugin::Swagger2 0.01 2014-12-04T14:01:27Z - Add load() - Add pod() and Swagger2::POD - Add to_string($format) - Started project Swagger2-0.89/cpanfile000644 000765 000024 00000000530 13027474543 016015 0ustar00jhthorsenstaff000000 000000 # You can install this projct with curl -L http://cpanmin.us | perl - https://github.com/jhthorsen/swagger2/archive/master.tar.gz requires "JSON::Validator" => "0.90"; requires "Mojolicious" => "6.00"; recommends "Data::Validate::Domain" => "0.10"; recommends "Data::Validate::IP" => "0.24"; test_requires "Test::More" => "0.88"; Swagger2-0.89/examples/000755 000765 000024 00000000000 13056113272 016120 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/lib/000755 000765 000024 00000000000 13056113272 015050 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/Makefile.PL000644 000765 000024 00000001417 13056113272 016257 0ustar00jhthorsenstaff000000 000000 # Generated by git-ship. See 'git-ship --man' for help or https://github.com/jhthorsen/app-git-ship use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Swagger2', AUTHOR => 'Jan Henning Thorsen ', LICENSE => 'artistic_2', ABSTRACT_FROM => 'lib/Swagger2.pm', VERSION_FROM => 'lib/Swagger2.pm', EXE_FILES => [qw( )], META_MERGE => { resources => { bugtracker => 'https://github.com/jhthorsen/swagger2/issues', homepage => 'https://github.com/jhthorsen/swagger2', repository => 'https://github.com/jhthorsen/swagger2.git', }, }, BUILD_REQUIRES => { 'Test::More' => '0.88' } , PREREQ_PM => { 'JSON::Validator' => '0.90', 'Mojolicious' => '6.00' } , test => {TESTS => (-e 'META.yml' ? 't/*.t' : 't/*.t xt/*.t')}, ); Swagger2-0.89/MANIFEST000644 000765 000024 00000001265 13056113272 015437 0ustar00jhthorsenstaff000000 000000 .perltidyrc .ship.conf .travis.yml Changes cpanfile examples/websocket.pl lib/Mojolicious/Command/swagger2.pm lib/Mojolicious/Plugin/Swagger2.pm lib/Swagger2.pm lib/Swagger2/Client.pm lib/Swagger2/Editor.pm lib/Swagger2/POD.pm lib/Swagger2/public/ace.js lib/Swagger2/public/mode-json.js lib/Swagger2/public/mode-yaml.js lib/Swagger2/public/theme-solarized_dark.js lib/Swagger2/public/worker-json.js lib/Swagger2/SchemaValidator.pm lib/Swagger2/swagger2-client.js Makefile.PL MANIFEST This list of files README t/00-basic.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Swagger2-0.89/META.json000664 000765 000024 00000002324 13056113272 015726 0ustar00jhthorsenstaff000000 000000 { "abstract" : "Deprecated", "author" : [ "Jan Henning Thorsen " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150005", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Swagger2", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "Test::More" : "0.88" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "JSON::Validator" : "0.90", "Mojolicious" : "6.00" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/jhthorsen/swagger2/issues" }, "homepage" : "https://github.com/jhthorsen/swagger2", "repository" : { "url" : "https://github.com/jhthorsen/swagger2.git" } }, "version" : "0.89", "x_serialization_backend" : "JSON::PP version 2.27300" } Swagger2-0.89/META.yml000664 000765 000024 00000001352 13056113272 015556 0ustar00jhthorsenstaff000000 000000 --- abstract: Deprecated author: - 'Jan Henning Thorsen ' build_requires: Test::More: '0.88' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150005' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Swagger2 no_index: directory: - t - inc requires: JSON::Validator: '0.90' Mojolicious: '6.00' resources: bugtracker: https://github.com/jhthorsen/swagger2/issues homepage: https://github.com/jhthorsen/swagger2 repository: https://github.com/jhthorsen/swagger2.git version: '0.89' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Swagger2-0.89/README000644 000765 000024 00000003326 13056113272 015166 0ustar00jhthorsenstaff000000 000000 NAME Swagger2 - Deprecated VERSION 0.89 DEPRECATION WARNING The Swagger2 distribution is no longer actively maintained. Only severe bug fixes and pull requests will move this code forward. The reason behind this is that the code is too complex and hard to maintain. So what should you use instead? * Swagger2 Swagger2 is either not very useful or replaced by JSON::Validator. * Swagger2::Client No alternatives. The issue with this module is that it does not understand if you have parameters with the same name. There might be a OpenAPI::Client at some point, but it is currently no plans to write it. * Swagger2::Editor No alternatives. * Swagger2::POD Swagger2::POD is not very good and also very hard to maintain. Mojolicious::Plugin::OpenAPI has a HTML renderer which makes documentation that is much easier to read and always in sync with the application. When that is said: The renderer in Mojolicious::Plugin::OpenAPI need refinement. * Swagger2::SchemaValidator Mojolicious::Plugin::OpenAPI has the validator built in. For other purposes, use JSON::Validator or JSON::Validator::OpenAPI instead. * Mojolicious::Command::swagger2 No alternatives. * Mojolicious::Plugin::Swagger2 Use Mojolicious::Plugin::OpenAPI instead. Mojolicious::Plugin::OpenAPI plays much nicer together with the Mojolicious framework. COPYRIGHT AND LICENSE Copyright (C) 2014-2015, Jan Henning Thorsen This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. AUTHOR Jan Henning Thorsen - "jhthorsen@cpan.org" Swagger2-0.89/t/000755 000765 000024 00000000000 13056113272 014545 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/t/00-basic.t000644 000765 000024 00000001343 13056112662 016233 0ustar00jhthorsenstaff000000 000000 use Test::More; use File::Find; if (!eval 'use Test::Pod; 1') { *Test::Pod::pod_file_ok = sub { SKIP: { skip "pod_file_ok(@_) (Test::Pod is required)", 1 } }; } if (!eval 'use Test::CPAN::Changes; 1') { *Test::CPAN::Changes::changes_file_ok = sub { SKIP: { skip "changes_ok(@_) (Test::CPAN::Changes is required)", 4 } }; } find( {wanted => sub { /\.pm$/ and push @files, $File::Find::name }, no_chdir => 1}, -e 'blib' ? 'blib' : 'lib', ); plan tests => @files * 2 + 4; for my $file (@files) { my $module = $file; $module =~ s,\.pm$,,; $module =~ s,.*/?lib/,,; $module =~ s,/,::,g; ok eval "use $module; 1", "use $module" or diag $@; Test::Pod::pod_file_ok($file); } Test::CPAN::Changes::changes_file_ok(); Swagger2-0.89/lib/Mojolicious/000755 000765 000024 00000000000 13056113272 017344 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/lib/Swagger2/000755 000765 000024 00000000000 13056113272 016531 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/lib/Swagger2.pm000644 000765 000024 00000012401 13056113272 017065 0ustar00jhthorsenstaff000000 000000 package Swagger2; use Mojo::Base -base; use Mojo::Asset::File; use Mojo::JSON; use Mojo::JSON::Pointer; use Mojo::URL; use File::Basename (); use File::Spec; use Mojo::Util 'deprecated'; use JSON::Validator::OpenAPI; our $VERSION = '0.89'; # Should be considered internal our $JS_CLIENT = File::Spec->catfile(File::Basename::dirname(__FILE__), 'Swagger2', 'swagger2-client.js'); deprecated "https://metacpan.org/pod/Swagger2#DEPRECATION-WARNING"; has api_spec => sub { my $self = shift; return $self->_validator->_load_schema($self->url) if '' . $self->url; return Mojo::JSON::Pointer->new({}); }; has base_url => sub { my $self = shift; my $url = Mojo::URL->new; my ($schemes, $v); $self->load if !$self->{api_spec} and '' . $self->url; $schemes = $self->api_spec->get('/schemes') || []; $url->host($self->api_spec->get('/host') || 'example.com'); $url->path($self->api_spec->get('/basePath') || '/'); $url->scheme($schemes->[0] || 'http'); return $url; }; has _specification => sub { shift->_validator->schema('http://swagger.io/v2/schema.json')->schema }; has _validator => sub { JSON::Validator::OpenAPI->new }; sub ua { shift->_validator->ua(@_) } sub url { shift->{url} } sub expand { my $self = shift; my $class = Scalar::Util::blessed($self); my $schema = $self->_validator->schema($self->api_spec->data)->schema; $class->new(%$self)->api_spec($schema); } sub find_operations { my ($self, $needle) = @_; my $paths = $self->api_spec->get('/paths'); my $operations = []; $needle ||= {}; $needle = {operationId => $needle} unless ref $needle; for my $path (keys %$paths) { next if $path =~ /^x-/; next if $needle->{path} and $needle->{path} ne $path; for my $method (keys %{$paths->{$path}}) { my $object = $paths->{$path}{$method}; next if $method =~ /^x-/; next if $needle->{tag} and !grep { $needle->{tag} eq $_ } @{$object->{tags} || []}; next if $needle->{method} and $needle->{method} ne $method; next if $needle->{operationId} and $needle->{operationId} ne $object->{operationId}; push @$operations, $object; } } return $operations; } sub javascript_client { Mojo::Asset::File->new(path => $JS_CLIENT) } sub load { my $self = shift; delete $self->{base_url}; $self->{url} = Mojo::URL->new(shift) if @_; $self->{api_spec} = $self->api_spec; $self; } sub new { my $class = shift; my $url = @_ % 2 ? shift : ''; my $self = $class->SUPER::new(@_); $url =~ s!^file://!!; $self->{url} ||= $url; $self->{url} = Mojo::URL->new($self->{url}) unless ref $self->{url}; $self; } sub parse { my ($self, $doc, $namespace) = @_; delete $self->{base_url}; $namespace ||= 'http://127.0.0.1/#'; $self->{url} = Mojo::URL->new($namespace); $self->{api_spec} = Mojo::JSON::Pointer->new($self->_validator->_load_schema_from_text($doc)); $self; } sub pod { my $self = shift; my $resolved = $self->_validator->schema($self->api_spec->data)->schema; require Swagger2::POD; Swagger2::POD->new(base_url => $self->base_url, api_spec => $resolved); } sub to_string { my $self = shift; my $format = shift || 'json'; return DumpYAML($self->api_spec->data) if $format eq 'yaml'; return Mojo::JSON::encode_json($self->api_spec->data); } sub validate { my $self = shift; $self->_validator->validate($self->expand->api_spec->data, $self->_specification->data); } sub _is_true { return $_[0] if ref $_[0] and !Scalar::Util::blessed($_[0]); return 0 if !$_[0] or $_[0] =~ /^(n|false|off)/i; return 1; } 1; =encoding utf8 =head1 NAME Swagger2 - Deprecated =head1 VERSION 0.89 =head1 DEPRECATION WARNING The L distribution is no longer actively maintained. Only severe bug fixes and pull requests will move this code forward. The reason behind this is that the code is too complex and hard to maintain. So what should you use instead? =over 2 =item * L L is either not very useful or replaced by L. =item * L No alternatives. The issue with this module is that it does not understand if you have parameters with the same name. There might be a L at some point, but it is currently no plans to write it. =item * L No alternatives. =item * L L is not very good and also very hard to maintain. L has a HTML renderer which makes documentation that is much easier to read and always in sync with the application. When that is said: The renderer in L need refinement. =item * L L has the validator built in. For other purposes, use L or L instead. =item * L No alternatives. =item * L Use L instead. L plays much nicer together with the L framework. =back =head1 COPYRIGHT AND LICENSE Copyright (C) 2014-2015, Jan Henning Thorsen This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. =head1 AUTHOR Jan Henning Thorsen - C =cut Swagger2-0.89/lib/Swagger2/Client.pm000644 000765 000024 00000012314 13056113206 020303 0ustar00jhthorsenstaff000000 000000 package Swagger2::Client; use Mojo::Base -base; use Mojo::JSON; use Mojo::UserAgent; use Mojo::Util; use Carp (); use Swagger2; use JSON::Validator::OpenAPI; use constant DEBUG => $ENV{SWAGGER2_DEBUG} || 0; has base_url => sub { Mojo::URL->new(shift->_swagger->base_url) }; has ua => sub { Mojo::UserAgent->new }; has _validator => sub { JSON::Validator::OpenAPI->new; }; sub generate { my $class = shift; my ($swagger, $url) = _swagger_url(shift); my $paths = $swagger->api_spec->get('/paths') || {}; my $generated; $generated = 40 < length $url ? Mojo::Util::md5_sum($url) : $url; # 40 is a bit random: not too long $generated =~ s!\W!_!g; $generated = "$class\::$generated"; return $generated->new if $generated->isa($class); # already generated _init_package($generated, $class); Mojo::Util::monkey_patch($generated, _swagger => sub {$swagger}); for my $path (keys %$paths) { for my $http_method (keys %{$paths->{$path}}) { my $op_spec = $paths->{$path}{$http_method}; my $method = $op_spec->{operationId} || $path; my $code = $generated->_generate_method(lc $http_method, $path, $op_spec); $method =~ s![^\w]!_!g; warn "[$generated] Add method $generated\::$method()\n" if DEBUG; Mojo::Util::monkey_patch($generated, $method => $code); my $snake = Mojo::Util::decamelize(ucfirst $method); warn "[$generated] Add method $generated\::$snake()\n" if DEBUG; Mojo::Util::monkey_patch($generated, $snake => $code); } } return $generated->new; } sub _generate_method { my ($class, $http_method, $path, $op_spec) = @_; my @path = grep {length} split '/', $path; return sub { my $cb = ref $_[-1] eq 'CODE' ? pop : undef; my $self = shift; my $args = shift || {}; my $req = [$self->base_url->clone]; my @e = $self->_validate_request($args, $op_spec, $req); if (@e) { unless ($cb) { return _invalid_input_res(\@e) if $self->return_on_error; Carp::croak('Invalid input: ' . join ' ', @e); } $self->$cb(\@e, undef); return $self; } push @{$req->[0]->path->parts}, map { local $_ = $_; s,\{(\w+)\},{$args->{$1}//''},ge; $_; } @path; if ($cb) { Scalar::Util::weaken($self); $self->ua->$http_method( @$req, sub { my ($ua, $tx) = @_; return $self->$cb('', $tx->res) unless my $err = $tx->error; return $self->$cb($err->{message}, $tx->res); } ); return $self; } else { my $tx = $self->ua->$http_method(@$req); return $tx->res if !$tx->error or $self->return_on_error; Carp::croak(join ': ', grep {defined} $tx->error->{message}, $tx->res->body); } }; } sub _init_package { my ($package, $base) = @_; eval <<"HERE" or die "package $package: $@"; package $package; use Mojo::Base '$base'; has return_on_error => 0; 1; HERE } sub _invalid_input_res { my $res = Mojo::Message::Response->new; $res->headers->content_type('application/json'); $res->body(Mojo::JSON::encode_json({errors => $_[0]})); $res->code(400)->message($res->default_message); $res->error({message => 'Invalid input', code => 400}); } sub _swagger_url { if (UNIVERSAL::isa($_[0], 'Swagger2')) { my $swagger = shift->load->expand; return ($swagger, $swagger->url); } else { my $url = shift; return (Swagger2->new->load($url)->expand, $url); } } sub _validate_request { my ($self, $args, $op_spec, $req) = @_; my $query = $req->[0]->query; my (%data, $body, @e); for my $p (@{$op_spec->{parameters} || []}) { my ($in, $name, $type) = @$p{qw(in name type)}; my $value = exists $args->{$name} ? $args->{$name} : $p->{default}; if (defined $value or Swagger2::_is_true($p->{required})) { $type ||= 'object'; if (defined $value) { $value += 0 if $type =~ /^(?:integer|number)/ and $value =~ /^\d/; $value = ($value eq 'false' or !$value) ? Mojo::JSON->false : Mojo::JSON->true if $type eq 'boolean'; } if ($in eq 'body') { warn "[Swagger2::Client] Validate $in\n" if DEBUG; push @e, map { $_->{path} = $_->{path} eq "/" ? "/$name" : "/$name$_->{path}"; $_; } $self->_validator->validate($value, $p->{schema}); } elsif ($in eq 'formData' and $type eq 'file') { warn "[Swagger2::Client] Validate $in file=$name (@{[defined $value ? 1 : 0]})\n" if DEBUG; } else { warn "[Swagger2::Client] Validate $in $name=$value\n" if DEBUG; push @e, $self->_validator->validate({$name => $value}, {properties => {$name => $p}}); } } if (not defined $value) { next; } elsif ($in eq 'query') { $query->param($name => $value); } elsif ($in eq 'header') { $req->[1]{$name} = $value; } elsif ($in eq 'body') { $data{json} = $value; } elsif ($in eq 'formData') { $data{form}{$name} = $value; } } push @$req, map { ($_ => $data{$_}) } keys %data; push @$req, $body if defined $body; return @e; } 1; =encoding utf8 =head1 NAME Swagger2::Client - Deprecated =head1 DEPRECATION WARNING See L. =head1 AUTHOR Jan Henning Thorsen - C =cut Swagger2-0.89/lib/Swagger2/Editor.pm000644 000765 000024 00000016553 13056113206 020324 0ustar00jhthorsenstaff000000 000000 package Swagger2::Editor; use Mojo::Base 'Mojolicious'; use Mojo::Util; use File::Basename; use Swagger2; has specification_file => sub { $ENV{SWAGGER_API_FILE} || '' }; has _swagger => sub { Swagger2->new }; sub _get { my $c = shift; $c->respond_to( txt => {data => $c->app->_swagger->pod->to_string, layout => undef}, any => sub { my $c = shift; $c->stash(layout => undef) if $c->req->is_xhr; $c->render(template => 'editor'); } ); } sub _post { my $c = shift; my $spec = $c->req->body || '{}'; my $file = $c->app->specification_file; eval { my $s = Swagger2->new->parse($spec); Mojo::Util::spurt($spec, $file) if $file and -w $file; $c->render(text => $c->podify($s->pod), layout => undef); } or do { my $e = $@; $c->app->log->error($e); $e =~ s!^(Could not.*?:)\s+!$1\n\n!s; $e =~ s!\s+at \S+\.pm line \d\S+!!g; $c->render(template => 'error', error => $e); }; } sub startup { my $self = shift; my $raw = ''; if (my $file = $self->specification_file) { $raw = $file =~ /^https?:/ ? $self->ua->get($file)->res->body : Mojo::Util::slurp(File::Spec->catfile(split '/', $file)); $self->_swagger->parse($raw, $file); } unshift @{$self->renderer->classes}, __PACKAGE__; unshift @{$self->static->paths}, File::Spec->catdir(File::Basename::dirname(__FILE__), 'public'); $self->routes->get('/' => \&_get); $self->routes->post('/' => \&_post); $self->defaults(raw => $raw, swagger => $self->_swagger, layout => 'default'); $self->plugin('PODRenderer'); $self->helper(podify => \&_podify); } sub _podify { my ($c, $pod) = @_; my $dom = Mojo::DOM->new($c->pod_to_html($pod->to_string)); my $ul = '
    '; my ($sub, @parts); for my $e ($dom->find('h1, h2')->each) { my $id = $e->{id}; my $text = $e->all_text; my $anchor = $c->tag(a => href => "#$id", sub {$text}); if ($e->type eq 'h1') { $ul .= '
' if $sub; $sub = 0; } else { $ul .= '
    ' unless $sub; $sub = 1; } $ul .= "
  • $anchor
  • "; $e->content($c->link_to($text => Mojo::URL->new->fragment('toc'), id => $id)); } $ul .= '
' if $ul; return $c->b(qq(

TABLE OF CONTENTS

$ul$dom
)); } $ENV{SWAGGER_LOAD_EDITOR} ? __PACKAGE__->new : 1; __DATA__ @@ error.html.ep % title "Error in specification";

Error in specification

<%= $error %>
@@ editor.html.ep % title "Editor";
<%= stash('raw') || '---' %>
 
<%= podify $swagger->pod %>
% my $ace_url = $c->req->url->base->path->clone; % push @{$ace_url->parts}, 'ace.js'; %= javascript begin (function(ace) { var localStorage = window.localStorage || {}; var draggable = document.getElementById("resizer"); var editor = document.getElementById("editor"); var preview = document.getElementById("preview"); var focusId = location.href.split("#")[1] || ""; var initializing = true; var tid, xhr, i; var loaded = function() { if (initializing) { ace.focus(); ace.gotoLine(2); } initializing = false; ace.session.setMode("ace/mode/" + (ace.getValue().match(/^\s*\{/) ? "json" : "yaml")); preview.scrollTop = scrollSave(); }; var render = function() { scrollSave(); xhr = new XMLHttpRequest(); xhr.open("POST", "<%= url_for("/") %>", true); xhr.onload = function() { preview.firstChild.innerHTML = xhr.responseText; loaded(); }; localStorage["swagger-spec"] = ace.getValue(); xhr.send(localStorage["swagger-spec"]); }; var scrollSave = function() { var elem = document.getElementById(location.href.split("#")[1] || "toc"); if (!elem) return 0; var last = scrollSave.last; scrollSave.last = preview.scrollTop || elem.offsetTop; return last || scrollSave.last; }; ace.commands.addCommand({ bindKey: { win: "Ctrl-L", mac: "Command-L" }, command: "passKeysToBrowser" }); ace.commands.addCommand({ name: "find", bindKey: { win: "Ctrl-F", mac: "Command-F" }, exec: function(editor) { editor.find(prompt("Find:", editor.getCopyText())); } }); ace.setTheme("ace/theme/solarized_dark"); ace.getSession().on("change", function(e) { if (initializing) return; if (tid) clearTimeout(tid); tid = setTimeout(render, 600); }); if (!focusId) { location.href = location.href + "#toc"; } if (focusId.indexOf("/") == 0) { xhr = new XMLHttpRequest(); xhr.open("GET", focusId, true); xhr.onload = function() { if (!xhr.responseText.match(/^\s*(---|{)/)) return alert("Could not load specification from " + focusId); ace.setValue(xhr.responseText); render(); }; xhr.send(false); location.href = location.href.replace(/\#.*/, "#toc"); } else if (localStorage["swagger-spec"]) { ace.setValue(localStorage["swagger-spec"]); render(); } else { loaded(); } var resize = function(width, done) { draggable.style.left = width + "px"; editor.style.width = width + "px"; preview.style.marginLeft = width + "px"; if(done) ace.resize(); }; resize.x = false; resize.w = localStorage["swagger-editor-width"]; if (resize.w) resize(resize.w, true); draggable.addEventListener("mousedown", function(e) { resize.x = e.clientX; resize.w = editor.offsetWidth; }); window.addEventListener("resize", function(e) { if (resize.w > this.innerWidth) resize(this.innerWidth - 30, true); }) window.addEventListener("mouseup", function(e) { if (resize.x === false) return; resize(resize.w + e.clientX - resize.x, true); resize.w = editor.offsetWidth; resize.x = false; localStorage["swagger-editor-width"] = resize.w; }); window.addEventListener("mousemove", function(e) { if (resize.x === false) return; e.preventDefault(); resize(resize.w + e.clientX - resize.x); }); })(ace.edit("editor")); % end @@ layouts/default.html.ep Swagger2 - <%= title %> %= stylesheet begin html, body { background: #f5f5f5; font-family: sans-serif; font-size: 14px; color: #111; margin: 0; padding: 0; height: 100%; width: 100%; } a { color: #222; } p { margin: 0.5em 0; } h1, h2, h3 { padding: 0; margin: 1em 0 0 0; } h1 { font-size: 2em; } h2 { font-size: 1.5em; border-bottom: 1px solid #bbb; } h3 { font-size: 1.2em; } h4 { font-size: 1em; } h1 a, h2 a, h3 a, h4 a { text-decoration: none; } h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover { text-decoration: underline; } #editor, #resizer { position: fixed; top: 0; bottom: 0; } #editor { font-size: 14px; left: 0; width: 620px; } #resizer { border-left: 4px solid rgba(25, 63, 73, 0.99); left: 620px; width: 4px; cursor: ew-resize; } #preview { overflow: auto; margin-left: 620px; height: 100%; } #preview .pod-container { padding-left: 10px; padding-bottom: 100px; } #preview .link:hover { color: #679; cursor: pointer; } @media print { #editor, #resizer { display: none; } #preview { margin: 0; width: 100%; height: auto; } #preview .pod-container { padding: 0; } } % end %= content 1; =encoding utf8 =head1 NAME Swagger2::Editor - Deprecated =head1 DEPRECATION WARNING See L. =head1 AUTHOR Jan Henning Thorsen - C =cut Swagger2-0.89/lib/Swagger2/POD.pm000644 000765 000024 00000025023 13056113206 017510 0ustar00jhthorsenstaff000000 000000 package Swagger2::POD; use Mojo::Base -base; use Mojo::JSON 'encode_json'; use Mojo::Message::Response; use Scalar::Util 'blessed'; use constant NO_DESCRIPTION => 'No description.'; require Swagger2; my $MOJO_MESSAGE_RESPONSE = Mojo::Message::Response->new; sub to_string { my $self = shift; join('', $self->_header_to_string, $self->_api_endpoint_to_string, $self->_paths_to_string, $self->_footer_to_string, ); } sub _api_endpoint_to_string { my $self = shift; my @schemes = @{$self->{api_spec}->get('/schemes') || []}; my $url = $self->{base_url}->clone; my $str = "=head1 BASEURL\n\n"; unless (@schemes) { return $str . "No default URL is defined to this application.\n\n"; } while (my $scheme = shift @schemes) { $url->scheme($scheme); $str .= sprintf "L<%s>\n\n", $url; } return $str; } sub _footer_to_string { my $self = shift; my $contact = $self->{api_spec}->get('/info/contact'); my $license = $self->{api_spec}->get('/info/license'); my $str = ''; unless ($license->{name}) { $license->{name} = 'BSD'; $license->{url} = 'http://www.linfo.org/bsdlicense.html'; } $contact->{name} ||= 'Unknown author'; $str .= sprintf "=head1 COPYRIGHT AND LICENSE\n\n%s", $contact->{name}; $str .= sprintf " - %s", $contact->{email} || $contact->{url} if $contact->{email} || $contact->{url}; $str .= sprintf "\n\n%s", $license->{name}; $str .= sprintf " - %s", $license->{url} if $license->{url}; $str .= "\n\n=cut\n"; $str; } sub _header_to_string { my $self = shift; my $info = $self->{api_spec}->get('/info'); my $str = ''; $info->{title} ||= 'Noname API'; $info->{description} ||= 'This API has no description.'; $info->{version} ||= '0.01'; $str .= sprintf "=head1 NAME\n\n%s\n\n", $info->{title}; $str .= sprintf "=head1 VERSION\n\n%s\n\n", $info->{version}; $str .= sprintf "=head1 DESCRIPTION\n\n%s\n\n", $info->{description}; $str .= sprintf "=head1 TERMS OF SERVICE\n\n%s\n\n", $info->{termsOfService} if $info->{termsOfService}; $str; } sub _path_request_to_string { my ($self, $info) = @_; my @table = ([qw( Name In Type Required Description )]); my $str = ''; my %body; for my $p (@{$info->{parameters} || []}) { $p->{description} ||= NO_DESCRIPTION; if ($p->{in} eq 'body') { %body = (name => 'body', %$p); push @table, [$p->{name}, 'body', 'schema', 'Yes', $p->{description}]; } else { push @table, [ @$p{qw( name in type )}, Swagger2::_is_true($p->{required}) ? 'Yes' : 'No', $p->{description} ]; } } $str .= sprintf "=head3 Parameters\n\n"; $str .= (@table == 1) ? "This resource takes no parameters.\n\n" : sprintf "%s\n", _ascii_table(\@table, ' '); $str .= " $body{name}:\n\n" . $self->_schema_to_string_dispatch($body{schema}, 0) . "\n" if %body; $str; } sub _path_response_to_string { my ($self, $info) = @_; my $responses = $info->{responses} || {}; my $str = ''; $str .= sprintf "=head3 Responses\n\n"; for my $code (sort keys %$responses) { my $res = $responses->{$code}; $str .= sprintf "=head4 %s\n\n", _status_code_to_string($code); $str .= $self->_summary_and_description($res); $str .= $self->_schema_to_string_dispatch($res->{schema}, 0) . "\n"; } return $str; } sub _paths_to_string { my $self = shift; my $paths = $self->{api_spec}->get('/paths') || {}; my $str = "=head1 RESOURCES\n\n"; my %info; for my $path (keys %$paths) { for my $method (sort keys %{$paths->{$path}}) { next if $method =~ /^x-/; my $operationId = $paths->{$path}{$method}{operationId} || join ' ', uc $method, $path; $info{$operationId} and die "Overlapping operationId in swagger specification: $operationId"; $info{$operationId} = {%{$paths->{$path}{$method}}, _path => $path, _method => $method,}; } } for my $operationId (sort keys %info) { my $url = $self->{base_url}->clone; my $info = $info{$operationId}; push @{$url->path->parts}, grep { length $_ } split '/', $info->{_path}; my $ext = $info->{externalDocs}; my $resource_url; $str .= sprintf "=head2 %s\n\n", $operationId; $str .= " THIS RESOURCE IS DEPRECATED!\n\n" if $info->{deprecated}; $str .= $self->_summary_and_description($info); $str .= sprintf "See also L<%s>\n\n", $ext->{url} if $ext; next METHOD if $info->{deprecated}; $url->query(Mojo::Parameters->new); $resource_url = $url->to_abs; $resource_url =~ s!/%7B([^%]+)%7D!/{$1}!g; $str .= sprintf "=head3 Resource URL\n\n"; $str .= sprintf " %s %s\n\n", uc $info->{_method}, $resource_url; $str .= $self->_path_request_to_string($info); $str .= $self->_path_response_to_string($info); } return $str; } sub _schema_anyof_to_string { my ($self, $schema, $depth) = @_; my $str = "\n" . _sprintf($depth + 1, "// Any of the below:\n"); for my $s (@{$schema->{anyOf}}) { $str .= _sprintf($depth + 1, ""); $str .= $self->_schema_to_string_dispatch($s, $depth + 1); } $str; } sub _schema_allof_to_string { my ($self, $schema, $depth) = @_; my $str = "\n" . _sprintf($depth + 1, "// All of the below:\n"); for my $s (@{$schema->{allOf}}) { $str .= _sprintf($depth + 1, ""); $str .= $self->_schema_to_string_dispatch($s, $depth + 1); } $str; } sub _schema_oneof_to_string { my ($self, $schema, $depth) = @_; my $str = "\n" . _sprintf($depth + 1, "// One of the below:\n"); for my $s (@{$schema->{oneOf}}) { $str .= _sprintf($depth + 1, ""); $str .= $self->_schema_to_string_dispatch($s, $depth + 1); } $str; } sub _schema_array_to_string { my ($self, $schema, $depth) = @_; my $description = _type_description($schema, qw( minItems maxItems multipleOf uniqueItems )); my $str = ''; $description = $description eq NO_DESCRIPTION ? "" : "// $description"; $str .= _sprintf($depth, "[%s\n", $description); $str .= $self->_schema_to_string_dispatch($schema->{items}, $depth + 1); $str .= _sprintf($depth + 1, "...\n"); $str .= _sprintf($depth, "]\n"); $str; } sub _schema_boolean_to_string { my ($self, $schema, $depth) = @_; sprintf "%s, // %s\n", 'boolean', _type_description($schema); } sub _schema_enum_to_string { my ($self, $schema, $depth) = @_; sprintf "%s, // %s\n", 'enum', _type_description($schema, qw( enum )); } sub _schema_integer_to_string { my ($self, $schema, $depth) = @_; sprintf "%s, // %s\n", $schema->{format} || 'integer', _type_description($schema, qw( default )); } sub _schema_number_to_string { my ($self, $schema, $depth) = @_; sprintf "%s, // %s\n", $schema->{format} || 'number', _type_description($schema, qw( default )); } sub _schema_file_to_string { my ($self, $schema, $depth) = @_; my $str = $schema->{description} || 'This response contains raw binary or text data.'; return " $str\n"; } sub _schema_object_to_string { my ($self, $schema, $depth) = @_; my $description = _type_description($schema, qw( minProperties maxProperties )); my $str = ''; $description = $description eq NO_DESCRIPTION ? "" : "// $description"; $str .= _sprintf($depth, "{%s\n", $description); for my $k (sort keys %$schema) { $str .= _sprintf($depth + 1, qq("%s": ), $k); $str .= $self->_schema_to_string_dispatch($schema->{$k}, $depth + 1) if ref $schema->{$k} eq 'HASH'; } $str .= _sprintf($depth, "},\n"); $str; } sub _schema_string_to_string { my ($self, $schema, $depth) = @_; sprintf "%s, // %s\n", $schema->{format} || 'string', _type_description($schema, qw( minLength maxLength pattern default )); } sub _schema_to_string_dispatch { my ($self, $schema, $depth) = @_; my $required = $schema->{required}; my $method; if ($schema->{properties}) { $schema = $schema->{properties}; } if ($required and ref $required eq 'ARRAY') { $schema->{$_}{required} = 1 for @$required; } if ($schema->{anyOf}) { $method = '_schema_anyof_to_string'; } elsif ($schema->{allOf}) { $method = '_schema_allof_to_string'; } elsif ($schema->{oneOf}) { $method = '_schema_oneof_to_string'; } elsif (ref $schema->{type} eq 'ARRAY') { return sprintf "{%s},\n", join ',', @{$schema->{type}}; } else { $method = '_schema_' . ($schema->{type} || 'object') . '_to_string'; } return "Cannot translate '$schema->{type}' into POD." unless $self->can($method); return $self->$method($schema, $depth); } sub _summary_and_description { my ($self, $data) = @_; my $str = ''; $str .= "$data->{summary}\n\n" if $data->{summary}; $str .= "$data->{description}\n\n" if $data->{description}; $str .= NO_DESCRIPTION . "\n\n" unless $data->{summary} or $data->{description}; $str; } # FUNCTIONS sub _ascii_table { my ($rows, $pad) = @_; my $width = 1; my (@spec, @table); $pad //= ''; for my $row (@$rows) { for my $i (0 .. $#$row) { $row->[$i] //= ''; $row->[$i] =~ s/[\r\n]//g; my $len = length $row->[$i]; $spec[$i] = $len if $len >= ($spec[$i] // 0); } } my $format = sprintf '%s| %s |', $pad, join ' | ', map { $width += $_ + 3; "\%-${_}s" } @spec; @table = map { sprintf "$format\n", @$_ } @$rows; unshift @table, "$pad." . ('-' x ($width - 2)) . ".\n"; splice @table, 2, 0, "$pad|" . ('-' x ($width - 2)) . "|\n"; push @table, "$pad'" . ('-' x ($width - 2)) . "'\n"; return join '', @table; } sub _sprintf { my ($level, $format, @args) = @_; sprintf "%s$format", (" " x (($level + 1) * 2)), @args; } sub _status_code_to_string { my ($code) = @_; my $message = $MOJO_MESSAGE_RESPONSE->code($code)->default_message; return sprintf '%s - %s', $code, $message if $message; return ucfirst $code; } sub _stringify { my ($k, $obj) = @_; return 'required' if $k eq 'required' and Swagger2::_is_true($obj->{$k}); return "$k=true" if blessed $obj->{$k} and $obj->{$k} eq Mojo::JSON->true; return "$k=false" if blessed $obj->{$k} and $obj->{$k} eq Mojo::JSON->false; return sprintf '%s=%s', $k, encode_json $obj->{$k} if ref $obj->{$k}; return sprintf '%s=%s', $k, $obj->{$k}; } sub _type_description { my ($schema) = (shift, shift); return $schema->{description} if $schema->{description}; my @keys = grep { defined $schema->{$_} } 'required', @_; my @description = map { _stringify($_, $schema) } @keys; return $schema->{title} || NO_DESCRIPTION unless @description; return join ', ', @description; } 1; =encoding utf8 =head1 NAME Swagger2::POD - Deprecated =head1 DEPRECATION WARNING See L. =head1 AUTHOR Jan Henning Thorsen - C =cut Swagger2-0.89/lib/Swagger2/public/000755 000765 000024 00000000000 13056113272 020007 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/lib/Swagger2/SchemaValidator.pm000644 000765 000024 00000000540 13056113206 022131 0ustar00jhthorsenstaff000000 000000 package Swagger2::SchemaValidator; use Mojo::Base 'JSON::Validator::OpenAPI'; warn "# Swagger2::SchemaValidator is deprecated in favor of JSON::Validator::OpenAPI"; 1; =encoding utf8 =head1 NAME Swagger2::SchemaValidator - Deprecated =head1 DEPRECATION WARNING See L. =head1 SEE ALSO L and L. =cut Swagger2-0.89/lib/Swagger2/swagger2-client.js000644 000765 000024 00000017427 12757311624 022107 0ustar00jhthorsenstaff000000 000000 (function() { /** * @file Generate object for communicating with a Swagger backend. * @version 0.70.0 * @author Jan Henning Thorsen * @copyright Jan Henning Thorsen 2016 * @license Artistic License version 2.0. */ /** * Generates a new client from a Swagger specification. * Note that the specification specification cannot contain "$ref" and need * to be in JSON format. * @class * @param {(string|Object)} spec - Either an object representing a Swagger spec or the URL to the Swagger specification file. * @param {function} [cb] - Function to call when the spec URL is downloaded. * @example * var client = new swaggerClient().load(url, function(err) { * if (err) throw err; * this.listPets({limit: 10}, function(err, xhr) { * console.log(xhr.code, xhr.body); * }); * }); */ window.swaggerClient = function(spec, cb) { this._id = 1; this._xhr = {}; if (typeof spec == "object") return this._generate(spec); if (typeof spec == "string") return this.load(spec, cb); }; var proto = window.swaggerClient.prototype; var makeErr; /** * Used to force running a request over plain HTTP instead of WebSocket. * @return {Object} client - Self. * @example * client = client.http().listPets({}, function(err, xhr) { }); */ proto.http = function() { this._http = true; return this; }; /** * Used to load a specification and generate methods. * @return {Object} client - Self. * @example * client = client.load(url, function(err) { }); */ proto.load = function(url, cb) { var xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onreadystatechange = function() { if (xhr.readyState != 4) return; if (xhr.status != 200) return cb.call(this, xhr.status); if (window.DEBUG == 1) console.log("[Swagger] Generate methods from " + url); this._generate(xhr.responseText.match(/^[\{\[]/) ? JSON.parse(xhr.responseText) : {}); cb.call(this, ""); }.bind(this); xhr.send(null); return this; }; /** * Used to set a WebSocket object which can talk Swagger. * The WebSocket object passed on need to either fire a "json" event * or the "onmessage" event will be taken over. * @return {Object} client - Self. * @example * client = client.ws(ws); * ws = client.ws(); */ proto.ws = function(ws) { var self = this; if (!ws) return self._ws; self._ws = ws; var handleResponse = function(json) { if (!json || !json.id || !json.code) return; var xhr = self._xhr[json.id]; if (!xhr) return; delete self._xhr[json.id]; xhr.status = json.code; xhr.body = json.body; if (window.DEBUG) console.log("[Swagger] " + xhr.op + " " + xhr.status + " " + JSON.stringify(xhr.body)); xhr.call(self, makeErr(xhr), xhr); }.bind(this); if (typeof ws.on == "function") { ws.on("json", handleResponse); } else { ws.onmessage = function(e) { var json = e.data.match(/^[\{\[]/) ? JSON.parse(e.data) : null; handleResponse(json); }; } return self; }; // Generate methods from spec proto._generate = function(spec) { var self = this; this.baseUrl = (spec.basePath || "").replace(/\/$/, ""); Object.keys(spec.paths).forEach(function(path) { if (path.indexOf("/") != 0) return; Object.keys(spec.paths[path]).forEach(function(httpMethod) { if (!httpMethod.match(/^\w+$/)) return; var opSpec = spec.paths[path][httpMethod]; var pathList = path.split("/"); httpMethod = httpMethod.toUpperCase(); pathList.shift(); // first element is empty string if (window.DEBUG == 2) console.log("[Swagger] Add method " + opSpec.operationId); self[opSpec.operationId] = function(input, cb) { var http = this._http; delete this._http; // reset on each request if (!http && this._ws && this._ws.readyState == WebSocket.OPEN) { this._ws.send(JSON.stringify({ id: this._id, op: opSpec.operationId, params: input })); this._xhr[this._id++] = cb; cb.op = opSpec.operationId; } else { var xhr = this._xhrReq(httpMethod, pathList, input, opSpec.parameters || []); if (xhr.errors) { setTimeout(function() { cb.call(this, xhr.errors, xhr); }.bind(this), 0); } else { xhr.onreadystatechange = function() { if (xhr.readyState != 4) return; if (window.DEBUG) console.log("[Swagger] " + xhr.url + " " + xhr.status + " " + xhr.responseText); xhr.body = xhr.responseText.match(/^[\{\[]/) ? JSON.parse(xhr.responseText) : xhr.responseText; cb.call(this, makeErr(xhr), xhr); }.bind(this); xhr.send(xhr.body); delete xhr.body; } } }; }); }); return this; }; // Create a request proto._xhrReq = function(httpMethod, pathList, input, parameters) { var xhr = new XMLHttpRequest(); var form = [], headers = [], json = null, query = [], str; var url = [this.baseUrl]; var errors = []; pathList.forEach(function(p) { url.push(p.replace(/\{(\w+)\}/, function(m, n) { if (typeof input[n] == "undefined") errors.push({ message: "Missing input: " + n, path: "/" + n }); return input[n]; })); }); xhr.body = null; xhr.url = url.join("/"); for (i = 0; i < parameters.length; i++) { var p = parameters[i]; var name = p.name; var value = input[name]; if (typeof value == "undefined") { value = p["default"]; } if (typeof value == "undefined") { if (p.required) errors.push({ message: "Missing input: " + name, path: "/" + name }); continue; } switch (p["in"]) { case "body": json = value; break; case "file": xhr.body = value; break; case "formData": form.push([name, value]); break; case "header": headers.push([name, value]); break; case "query": query.push([name, value]); break; } } if (errors.length) { if (window.DEBUG) console.log("[Swagger] " + xhr.url + " = " + JSON.stringify(errors)); xhr.errors = errors; return xhr; } if (query.length) { str = []; query.forEach(function(i) { str.push(encodeURIComponent(i[0]) + "=" + encodeURIComponent(i[1])); }); xhr.url += "?" + str.join("&"); } if (json) { headers.unshift(["Content-Type", "application/json"]); xhr.body = JSON.stringify(json); if (window.DEBUG == 2) console.log("[Swagger] " + xhr.url + " <<< " + xhr.body); } else if (form.length) { str = []; headers.unshift(["Content-Type", "application/x-www-form-urlencoded"]); form.forEach(function(i) { str.push(encodeURIComponent(i[0]) + "=" + encodeURIComponent(i[1])); }); xhr.body = str.join("&"); if (window.DEBUG == 2) console.log("[Swagger] " + xhr.url + " <<< " + xhr.body); } xhr.open(httpMethod, xhr.url); headers.forEach(function(i) { xhr.setRequestHeader(i[0], i[1]); }); return xhr; }; var makeErr = function(xhr) { var errors = xhr.body.errors || []; if (xhr.status == 200) return null; if (errors.length) return errors; if (!xhr.status) xhr.status = 408; return [{ message: "Request failed! Try again later. (" + xhr.status + ")", path: xhr.url }]; }; })(); Swagger2-0.89/lib/Swagger2/public/ace.js000644 000765 000024 00002307613 12757311624 021121 0ustar00jhthorsenstaff000000 000000 /* ***** BEGIN LICENSE BLOCK ***** * Distributed under the BSD license: * * Copyright (c) 2010, Ajax.org B.V. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Ajax.org B.V. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ /** * Define a module along with a payload * @param module a name for the payload * @param payload a function to call with (require, exports, module) params */ (function() { var ACE_NAMESPACE = "ace"; var global = (function() { return this; })(); if (!ACE_NAMESPACE && typeof requirejs !== "undefined") return; var _define = function(module, deps, payload) { if (typeof module !== 'string') { if (_define.original) _define.original.apply(window, arguments); else { console.error('dropping module because define wasn\'t a string.'); console.trace(); } return; } if (arguments.length == 2) payload = deps; if (!_define.modules) { _define.modules = {}; _define.payloads = {}; } _define.payloads[module] = payload; _define.modules[module] = null; }; /** * Get at functionality ace.define()ed using the function above */ var _require = function(parentId, module, callback) { if (Object.prototype.toString.call(module) === "[object Array]") { var params = []; for (var i = 0, l = module.length; i < l; ++i) { var dep = lookup(parentId, module[i]); if (!dep && _require.original) return _require.original.apply(window, arguments); params.push(dep); } if (callback) { callback.apply(null, params); } } else if (typeof module === 'string') { var payload = lookup(parentId, module); if (!payload && _require.original) return _require.original.apply(window, arguments); if (callback) { callback(); } return payload; } else { if (_require.original) return _require.original.apply(window, arguments); } }; var normalizeModule = function(parentId, moduleName) { // normalize plugin requires if (moduleName.indexOf("!") !== -1) { var chunks = moduleName.split("!"); return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]); } // normalize relative requires if (moduleName.charAt(0) == ".") { var base = parentId.split("/").slice(0, -1).join("/"); moduleName = base + "/" + moduleName; while(moduleName.indexOf(".") !== -1 && previous != moduleName) { var previous = moduleName; moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); } } return moduleName; }; /** * Internal function to lookup moduleNames and resolve them by calling the * definition function if needed. */ var lookup = function(parentId, moduleName) { moduleName = normalizeModule(parentId, moduleName); var module = _define.modules[moduleName]; if (!module) { module = _define.payloads[moduleName]; if (typeof module === 'function') { var exports = {}; var mod = { id: moduleName, uri: '', exports: exports, packaged: true }; var req = function(module, callback) { return _require(moduleName, module, callback); }; var returnValue = module(req, exports, mod); exports = returnValue || mod.exports; _define.modules[moduleName] = exports; delete _define.payloads[moduleName]; } module = _define.modules[moduleName] = exports || module; } return module; }; function exportAce(ns) { var require = function(module, callback) { return _require("", module, callback); }; var root = global; if (ns) { if (!global[ns]) global[ns] = {}; root = global[ns]; } if (!root.define || !root.define.packaged) { _define.original = root.define; root.define = _define; root.define.packaged = true; } if (!root.require || !root.require.packaged) { _require.original = root.require; root.require = require; root.require.packaged = true; } } exportAce(ACE_NAMESPACE); })(); ace.define("ace/lib/regexp",["require","exports","module"], function(require, exports, module) { "use strict"; var real = { exec: RegExp.prototype.exec, test: RegExp.prototype.test, match: String.prototype.match, replace: String.prototype.replace, split: String.prototype.split }, compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups compliantLastIndexIncrement = function () { var x = /^/g; real.test.call(x, ""); return !x.lastIndex; }(); if (compliantLastIndexIncrement && compliantExecNpcg) return; RegExp.prototype.exec = function (str) { var match = real.exec.apply(this, arguments), name, r2; if ( typeof(str) == 'string' && match) { if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) { r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", "")); real.replace.call(str.slice(match.index), r2, function () { for (var i = 1; i < arguments.length - 2; i++) { if (arguments[i] === undefined) match[i] = undefined; } }); } if (this._xregexp && this._xregexp.captureNames) { for (var i = 1; i < match.length; i++) { name = this._xregexp.captureNames[i - 1]; if (name) match[name] = match[i]; } } if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index)) this.lastIndex--; } return match; }; if (!compliantLastIndexIncrement) { RegExp.prototype.test = function (str) { var match = real.exec.call(this, str); if (match && this.global && !match[0].length && (this.lastIndex > match.index)) this.lastIndex--; return !!match; }; } function getNativeFlags (regex) { return (regex.global ? "g" : "") + (regex.ignoreCase ? "i" : "") + (regex.multiline ? "m" : "") + (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3 (regex.sticky ? "y" : ""); } function indexOf (array, item, from) { if (Array.prototype.indexOf) // Use the native array method if available return array.indexOf(item, from); for (var i = from || 0; i < array.length; i++) { if (array[i] === item) return i; } return -1; } }); ace.define("ace/lib/es5-shim",["require","exports","module"], function(require, exports, module) { function Empty() {} if (!Function.prototype.bind) { Function.prototype.bind = function bind(that) { // .length is 1 var target = this; if (typeof target != "function") { throw new TypeError("Function.prototype.bind called on incompatible " + target); } var args = slice.call(arguments, 1); // for normal call var bound = function () { if (this instanceof bound) { var result = target.apply( this, args.concat(slice.call(arguments)) ); if (Object(result) === result) { return result; } return this; } else { return target.apply( that, args.concat(slice.call(arguments)) ); } }; if(target.prototype) { Empty.prototype = target.prototype; bound.prototype = new Empty(); Empty.prototype = null; } return bound; }; } var call = Function.prototype.call; var prototypeOfArray = Array.prototype; var prototypeOfObject = Object.prototype; var slice = prototypeOfArray.slice; var _toString = call.bind(prototypeOfObject.toString); var owns = call.bind(prototypeOfObject.hasOwnProperty); var defineGetter; var defineSetter; var lookupGetter; var lookupSetter; var supportsAccessors; if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { defineGetter = call.bind(prototypeOfObject.__defineGetter__); defineSetter = call.bind(prototypeOfObject.__defineSetter__); lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); } if ([1,2].splice(0).length != 2) { if(function() { // test IE < 9 to splice bug - see issue #138 function makeArray(l) { var a = new Array(l+2); a[0] = a[1] = 0; return a; } var array = [], lengthBefore; array.splice.apply(array, makeArray(20)); array.splice.apply(array, makeArray(26)); lengthBefore = array.length; //46 array.splice(5, 0, "XXX"); // add one element lengthBefore + 1 == array.length if (lengthBefore + 1 == array.length) { return true;// has right splice implementation without bugs } }()) {//IE 6/7 var array_splice = Array.prototype.splice; Array.prototype.splice = function(start, deleteCount) { if (!arguments.length) { return []; } else { return array_splice.apply(this, [ start === void 0 ? 0 : start, deleteCount === void 0 ? (this.length - start) : deleteCount ].concat(slice.call(arguments, 2))) } }; } else {//IE8 Array.prototype.splice = function(pos, removeCount){ var length = this.length; if (pos > 0) { if (pos > length) pos = length; } else if (pos == void 0) { pos = 0; } else if (pos < 0) { pos = Math.max(length + pos, 0); } if (!(pos+removeCount < length)) removeCount = length - pos; var removed = this.slice(pos, pos+removeCount); var insert = slice.call(arguments, 2); var add = insert.length; if (pos === length) { if (add) { this.push.apply(this, insert); } } else { var remove = Math.min(removeCount, length - pos); var tailOldPos = pos + remove; var tailNewPos = tailOldPos + add - remove; var tailCount = length - tailOldPos; var lengthAfterRemove = length - remove; if (tailNewPos < tailOldPos) { // case A for (var i = 0; i < tailCount; ++i) { this[tailNewPos+i] = this[tailOldPos+i]; } } else if (tailNewPos > tailOldPos) { // case B for (i = tailCount; i--; ) { this[tailNewPos+i] = this[tailOldPos+i]; } } // else, add == remove (nothing to do) if (add && pos === lengthAfterRemove) { this.length = lengthAfterRemove; // truncate array this.push.apply(this, insert); } else { this.length = lengthAfterRemove + add; // reserves space for (i = 0; i < add; ++i) { this[pos+i] = insert[i]; } } } return removed; }; } } if (!Array.isArray) { Array.isArray = function isArray(obj) { return _toString(obj) == "[object Array]"; }; } var boxedString = Object("a"), splitString = boxedString[0] != "a" || !(0 in boxedString); if (!Array.prototype.forEach) { Array.prototype.forEach = function forEach(fun /*, thisp*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, thisp = arguments[1], i = -1, length = self.length >>> 0; if (_toString(fun) != "[object Function]") { throw new TypeError(); // TODO message } while (++i < length) { if (i in self) { fun.call(thisp, self[i], i, object); } } }; } if (!Array.prototype.map) { Array.prototype.map = function map(fun /*, thisp*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0, result = Array(length), thisp = arguments[1]; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self) result[i] = fun.call(thisp, self[i], i, object); } return result; }; } if (!Array.prototype.filter) { Array.prototype.filter = function filter(fun /*, thisp */) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0, result = [], value, thisp = arguments[1]; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self) { value = self[i]; if (fun.call(thisp, value, i, object)) { result.push(value); } } } return result; }; } if (!Array.prototype.every) { Array.prototype.every = function every(fun /*, thisp */) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0, thisp = arguments[1]; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self && !fun.call(thisp, self[i], i, object)) { return false; } } return true; }; } if (!Array.prototype.some) { Array.prototype.some = function some(fun /*, thisp */) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0, thisp = arguments[1]; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self && fun.call(thisp, self[i], i, object)) { return true; } } return false; }; } if (!Array.prototype.reduce) { Array.prototype.reduce = function reduce(fun /*, initial*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } if (!length && arguments.length == 1) { throw new TypeError("reduce of empty array with no initial value"); } var i = 0; var result; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i++]; break; } if (++i >= length) { throw new TypeError("reduce of empty array with no initial value"); } } while (true); } for (; i < length; i++) { if (i in self) { result = fun.call(void 0, result, self[i], i, object); } } return result; }; } if (!Array.prototype.reduceRight) { Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } if (!length && arguments.length == 1) { throw new TypeError("reduceRight of empty array with no initial value"); } var result, i = length - 1; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i--]; break; } if (--i < 0) { throw new TypeError("reduceRight of empty array with no initial value"); } } while (true); } do { if (i in this) { result = fun.call(void 0, result, self[i], i, object); } } while (i--); return result; }; } if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { var self = splitString && _toString(this) == "[object String]" ? this.split("") : toObject(this), length = self.length >>> 0; if (!length) { return -1; } var i = 0; if (arguments.length > 1) { i = toInteger(arguments[1]); } i = i >= 0 ? i : Math.max(0, length + i); for (; i < length; i++) { if (i in self && self[i] === sought) { return i; } } return -1; }; } if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { var self = splitString && _toString(this) == "[object String]" ? this.split("") : toObject(this), length = self.length >>> 0; if (!length) { return -1; } var i = length - 1; if (arguments.length > 1) { i = Math.min(i, toInteger(arguments[1])); } i = i >= 0 ? i : length - Math.abs(i); for (; i >= 0; i--) { if (i in self && sought === self[i]) { return i; } } return -1; }; } if (!Object.getPrototypeOf) { Object.getPrototypeOf = function getPrototypeOf(object) { return object.__proto__ || ( object.constructor ? object.constructor.prototype : prototypeOfObject ); }; } 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 (!owns(object, property)) return; var descriptor, getter, setter; descriptor = { enumerable: true, configurable: true }; if (supportsAccessors) { var prototype = object.__proto__; object.__proto__ = prototypeOfObject; var getter = lookupGetter(object, property); var setter = lookupSetter(object, property); object.__proto__ = prototype; if (getter || setter) { if (getter) descriptor.get = getter; if (setter) descriptor.set = setter; return descriptor; } } descriptor.value = object[property]; return descriptor; }; } if (!Object.getOwnPropertyNames) { Object.getOwnPropertyNames = function getOwnPropertyNames(object) { return Object.keys(object); }; } if (!Object.create) { var createEmpty; if (Object.prototype.__proto__ === null) { createEmpty = function () { return { "__proto__": null }; }; } else { createEmpty = function () { var empty = {}; for (var i in empty) empty[i] = null; empty.constructor = empty.hasOwnProperty = empty.propertyIsEnumerable = empty.isPrototypeOf = empty.toLocaleString = empty.toString = empty.valueOf = empty.__proto__ = null; return empty; } } Object.create = function create(prototype, properties) { var object; if (prototype === null) { object = createEmpty(); } else { if (typeof prototype != "object") throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); var Type = function () {}; Type.prototype = prototype; object = new Type(); object.__proto__ = prototype; } if (properties !== void 0) Object.defineProperties(object, properties); return object; }; } function doesDefinePropertyWork(object) { try { Object.defineProperty(object, "sentinel", {}); return "sentinel" in object; } catch (exception) { } } if (Object.defineProperty) { var definePropertyWorksOnObject = doesDefinePropertyWork({}); var definePropertyWorksOnDom = typeof document == "undefined" || doesDefinePropertyWork(document.createElement("div")); if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { var definePropertyFallback = Object.defineProperty; } } if (!Object.defineProperty || definePropertyFallback) { var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + "on this javascript engine"; Object.defineProperty = function defineProperty(object, property, descriptor) { if ((typeof object != "object" && typeof object != "function") || object === null) throw new TypeError(ERR_NON_OBJECT_TARGET + object); if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); if (definePropertyFallback) { try { return definePropertyFallback.call(Object, object, property, descriptor); } catch (exception) { } } if (owns(descriptor, "value")) { if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) { var prototype = object.__proto__; object.__proto__ = prototypeOfObject; delete object[property]; object[property] = descriptor.value; object.__proto__ = prototype; } else { object[property] = descriptor.value; } } else { if (!supportsAccessors) throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); if (owns(descriptor, "get")) defineGetter(object, property, descriptor.get); if (owns(descriptor, "set")) defineSetter(object, property, descriptor.set); } return object; }; } 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; }; } if (!Object.seal) { Object.seal = function seal(object) { return object; }; } if (!Object.freeze) { Object.freeze = function freeze(object) { return object; }; } 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); } if (!Object.preventExtensions) { Object.preventExtensions = function preventExtensions(object) { return object; }; } if (!Object.isSealed) { Object.isSealed = function isSealed(object) { return false; }; } if (!Object.isFrozen) { Object.isFrozen = function isFrozen(object) { return false; }; } if (!Object.isExtensible) { Object.isExtensible = function isExtensible(object) { if (Object(object) === object) { throw new TypeError(); // TODO message } var name = ''; while (owns(object, name)) { name += '?'; } object[name] = true; var returnValue = owns(object, name); delete object[name]; return returnValue; }; } 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; }; } if (!Date.now) { Date.now = function now() { return new Date().getTime(); }; } var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + "\u2029\uFEFF"; if (!String.prototype.trim || ws.trim()) { ws = "[" + ws + "]"; var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), trimEndRegexp = new RegExp(ws + ws + "*$"); String.prototype.trim = function trim() { return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); }; } function toInteger(n) { n = +n; if (n !== n) { // isNaN n = 0; } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } return n; } function isPrimitive(input) { var type = typeof input; return ( input === null || type === "undefined" || type === "boolean" || type === "number" || type === "string" ); } function toPrimitive(input) { var val, valueOf, toString; if (isPrimitive(input)) { return input; } valueOf = input.valueOf; if (typeof valueOf === "function") { val = valueOf.call(input); if (isPrimitive(val)) { return val; } } toString = input.toString; if (typeof toString === "function") { val = toString.call(input); if (isPrimitive(val)) { return val; } } throw new TypeError(); } var toObject = function (o) { if (o == null) { // this matches both null and undefined throw new TypeError("can't convert "+o+" to object"); } return Object(o); }; }); ace.define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"], function(require, exports, module) { "use strict"; require("./regexp"); require("./es5-shim"); }); ace.define("ace/lib/dom",["require","exports","module"], function(require, exports, module) { "use strict"; if (typeof document == "undefined") return; var XHTML_NS = "http://www.w3.org/1999/xhtml"; exports.getDocumentHead = function(doc) { if (!doc) doc = document; return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement; } exports.createElement = function(tag, ns) { return document.createElementNS ? document.createElementNS(ns || XHTML_NS, tag) : document.createElement(tag); }; exports.hasCssClass = function(el, name) { var classes = (el.className || "").split(/\s+/g); return classes.indexOf(name) !== -1; }; exports.addCssClass = function(el, name) { if (!exports.hasCssClass(el, name)) { el.className += " " + name; } }; 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; }; exports.setCssClass = function(node, className, include) { if (include) { exports.addCssClass(node, className); } else { exports.removeCssClass(node, className); } }; exports.hasCssString = function(id, doc) { var index = 0, sheets; doc = doc || document; if (doc.createStyleSheet && (sheets = doc.styleSheets)) { while (index < sheets.length) if (sheets[index++].owningElement.id === id) return true; } else if ((sheets = doc.getElementsByTagName("style"))) { while (index < sheets.length) if (sheets[index++].id === id) return true; } return false; }; exports.importCssString = function importCssString(cssText, id, doc) { doc = doc || document; if (id && exports.hasCssString(id, doc)) return null; var style; if (doc.createStyleSheet) { style = doc.createStyleSheet(); style.cssText = cssText; if (id) style.owningElement.id = id; } else { style = doc.createElementNS ? doc.createElementNS(XHTML_NS, "style") : doc.createElement("style"); style.appendChild(doc.createTextNode(cssText)); if (id) style.id = id; exports.getDocumentHead(doc).appendChild(style); } }; exports.importCssStylsheet = function(uri, doc) { if (doc.createStyleSheet) { doc.createStyleSheet(uri); } else { var link = exports.createElement('link'); link.rel = 'stylesheet'; link.href = uri; exports.getDocumentHead(doc).appendChild(link); } }; exports.getInnerWidth = function(element) { return ( parseInt(exports.computedStyle(element, "paddingLeft"), 10) + parseInt(exports.computedStyle(element, "paddingRight"), 10) + element.clientWidth ); }; exports.getInnerHeight = function(element) { return ( parseInt(exports.computedStyle(element, "paddingTop"), 10) + parseInt(exports.computedStyle(element, "paddingBottom"), 10) + 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(document) { var inner = exports.createElement("ace_inner"); inner.style.width = "100%"; inner.style.minWidth = "0px"; inner.style.height = "200px"; inner.style.display = "block"; var outer = exports.createElement("ace_outer"); var style = outer.style; style.position = "absolute"; style.left = "-10000px"; style.overflow = "hidden"; style.width = "200px"; style.minWidth = "0px"; style.height = "150px"; style.display = "block"; outer.appendChild(inner); var body = document.documentElement; body.appendChild(outer); var noScrollbar = inner.offsetWidth; style.overflow = "scroll"; var withScrollbar = inner.offsetWidth; if (noScrollbar == withScrollbar) { withScrollbar = outer.clientWidth; } body.removeChild(outer); return noScrollbar-withScrollbar; }; exports.setInnerHtml = function(el, innerHtml) { var element = el.cloneNode(false);//document.createElement("div"); element.innerHTML = innerHtml; el.parentNode.replaceChild(element, el); return element; }; if ("textContent" in document.documentElement) { exports.setInnerText = function(el, innerText) { el.textContent = innerText; }; exports.getInnerText = function(el) { return el.textContent; }; } else { exports.setInnerText = function(el, innerText) { el.innerText = innerText; }; exports.getInnerText = function(el) { return el.innerText; }; } exports.getParentWindow = function(document) { return document.defaultView || document.parentWindow; }; }); ace.define("ace/lib/oop",["require","exports","module"], function(require, exports, module) { "use strict"; exports.inherits = function(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; exports.mixin = function(obj, mixin) { for (var key in mixin) { obj[key] = mixin[key]; } return obj; }; exports.implement = function(proto, mixin) { exports.mixin(proto, mixin); }; }); ace.define("ace/lib/keys",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop"], function(require, exports, module) { "use strict"; require("./fixoldbrowsers"); var oop = require("./oop"); var Keys = (function() { var ret = { MODIFIER_KEYS: { 16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta' }, KEY_MODS: { "ctrl": 1, "alt": 2, "option" : 2, "shift": 4, "super": 8, "meta": 8, "command": 8, "cmd": 8 }, FUNCTION_KEYS : { 8 : "Backspace", 9 : "Tab", 13 : "Return", 19 : "Pause", 27 : "Esc", 32 : "Space", 33 : "PageUp", 34 : "PageDown", 35 : "End", 36 : "Home", 37 : "Left", 38 : "Up", 39 : "Right", 40 : "Down", 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", 115: "F4", 116: "F5", 117: "F6", 118: "F7", 119: "F8", 120: "F9", 121: "F10", 122: "F11", 123: "F12", 144: "Numlock", 145: "Scrolllock" }, PRINTABLE_KEYS: { 32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a', 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h', 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: '.', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',221: ']', 222: '\'' } }; var name, i; for (i in ret.FUNCTION_KEYS) { name = ret.FUNCTION_KEYS[i].toLowerCase(); ret[name] = parseInt(i, 10); } for (i in ret.PRINTABLE_KEYS) { name = ret.PRINTABLE_KEYS[i].toLowerCase(); ret[name] = parseInt(i, 10); } oop.mixin(ret, ret.MODIFIER_KEYS); oop.mixin(ret, ret.PRINTABLE_KEYS); oop.mixin(ret, ret.FUNCTION_KEYS); ret.enter = ret["return"]; ret.escape = ret.esc; ret.del = ret["delete"]; 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) { var keyString = Keys[keyCode]; if (typeof keyString != "string") keyString = String.fromCharCode(keyCode); return keyString.toLowerCase(); }; }); ace.define("ace/lib/useragent",["require","exports","module"], function(require, exports, module) { "use strict"; exports.OS = { LINUX: "LINUX", MAC: "MAC", WINDOWS: "WINDOWS" }; exports.getOS = function() { if (exports.isMac) { return exports.OS.MAC; } else if (exports.isLinux) { return exports.OS.LINUX; } else { return exports.OS.WINDOWS; } }; if (typeof navigator != "object") return; var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase(); var ua = navigator.userAgent; exports.isWin = (os == "win"); exports.isMac = (os == "mac"); exports.isLinux = (os == "linux"); exports.isIE = (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0) ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]) : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie exports.isOldIE = exports.isIE && exports.isIE < 9; exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === "Gecko"; exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv\:(\d+)/)||[])[1], 10) < 4; exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]"; exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined; exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined; exports.isAIR = ua.indexOf("AdobeAIR") >= 0; exports.isIPad = ua.indexOf("iPad") >= 0; exports.isTouchPad = ua.indexOf("TouchPad") >= 0; exports.isChromeOS = ua.indexOf(" CrOS ") >= 0; }); ace.define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) { "use strict"; var keys = require("./keys"); var useragent = require("./useragent"); exports.addListener = function(elem, type, callback) { if (elem.addEventListener) { return elem.addEventListener(type, callback, false); } if (elem.attachEvent) { var wrapper = function() { callback.call(elem, window.event); }; callback._wrapper = wrapper; elem.attachEvent("on" + type, wrapper); } }; exports.removeListener = function(elem, type, callback) { if (elem.removeEventListener) { return elem.removeEventListener(type, callback, false); } if (elem.detachEvent) { elem.detachEvent("on" + type, callback._wrapper || callback); } }; 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.getButton = function(e) { if (e.type == "dblclick") return 0; if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey))) return 2; if (e.preventDefault) { return e.button; } else { return {1:0, 2:2, 4:1}[e.button]; } }; exports.capture = function(el, eventHandler, releaseCaptureHandler) { function onMouseUp(e) { eventHandler && eventHandler(e); releaseCaptureHandler && releaseCaptureHandler(e); exports.removeListener(document, "mousemove", eventHandler, true); exports.removeListener(document, "mouseup", onMouseUp, true); exports.removeListener(document, "dragstart", onMouseUp, true); } exports.addListener(document, "mousemove", eventHandler, true); exports.addListener(document, "mouseup", onMouseUp, true); exports.addListener(document, "dragstart", onMouseUp, true); return onMouseUp; }; exports.addMouseWheelListener = function(el, callback) { if ("onmousewheel" in el) { exports.addListener(el, "mousewheel", function(e) { var factor = 8; if (e.wheelDeltaX !== undefined) { e.wheelX = -e.wheelDeltaX / factor; e.wheelY = -e.wheelDeltaY / factor; } else { e.wheelX = 0; e.wheelY = -e.wheelDelta / factor; } callback(e); }); } else if ("onwheel" in el) { exports.addListener(el, "wheel", function(e) { var factor = 0.35; switch (e.deltaMode) { case e.DOM_DELTA_PIXEL: e.wheelX = e.deltaX * factor || 0; e.wheelY = e.deltaY * factor || 0; break; case e.DOM_DELTA_LINE: case e.DOM_DELTA_PAGE: e.wheelX = (e.deltaX || 0) * 5; e.wheelY = (e.deltaY || 0) * 5; break; } callback(e); }); } else { exports.addListener(el, "DOMMouseScroll", function(e) { if (e.axis && e.axis == e.HORIZONTAL_AXIS) { e.wheelX = (e.detail || 0) * 5; e.wheelY = 0; } else { e.wheelX = 0; e.wheelY = (e.detail || 0) * 5; } callback(e); }); } }; exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbackName) { var clicks = 0; var startX, startY, timer; var eventNames = { 2: "dblclick", 3: "tripleclick", 4: "quadclick" }; exports.addListener(el, "mousedown", function(e) { if (exports.getButton(e) !== 0) { clicks = 0; } else if (e.detail > 1) { clicks++; if (clicks > 4) clicks = 1; } else { clicks = 1; } if (useragent.isIE) { var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5; if (!timer || isNewClick) clicks = 1; if (timer) clearTimeout(timer); timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600); if (clicks == 1) { startX = e.clientX; startY = e.clientY; } } e._clicks = clicks; eventHandler[callbackName]("mousedown", e); if (clicks > 4) clicks = 0; else if (clicks > 1) return eventHandler[callbackName](eventNames[clicks], e); }); if (useragent.isOldIE) { exports.addListener(el, "dblclick", function(e) { clicks = 2; if (timer) clearTimeout(timer); timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600); eventHandler[callbackName]("mousedown", e); eventHandler[callbackName](eventNames[clicks], e); }); } }; var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window) ? function(e) { return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0); } : function(e) { return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0); }; exports.getModifierString = function(e) { return keys.KEY_MODS[getModifierHash(e)]; }; function normalizeCommandKeys(callback, e, keyCode) { var hashId = getModifierHash(e); if (!useragent.isMac && pressedKeys) { if (pressedKeys[91] || pressedKeys[92]) hashId |= 8; if (pressedKeys.altGr) { if ((3 & hashId) != 3) pressedKeys.altGr = 0; else return; } if (keyCode === 18 || keyCode === 17) { var location = "location" in e ? e.location : e.keyLocation; if (keyCode === 17 && location === 1) { ts = e.timeStamp; } else if (keyCode === 18 && hashId === 3 && location === 2) { var dt = -ts; ts = e.timeStamp; dt += ts; if (dt < 3) pressedKeys.altGr = true; } } } 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 = -1; } if (hashId & 8 && (keyCode === 91 || keyCode === 93)) { keyCode = -1; } if (!hashId && keyCode === 13) { var location = "location" in e ? e.location : e.keyLocation; if (location === 3) { callback(e, hashId, -keyCode); if (e.defaultPrevented) return; } } if (useragent.isChromeOS && hashId & 8) { callback(e, hashId, keyCode); if (e.defaultPrevented) return; else hashId &= ~8; } if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) { return false; } return callback(e, hashId, keyCode); } var pressedKeys = null; var ts = 0; exports.addCommandKeyListener = function(el, callback) { var addListener = exports.addListener; if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) { var lastKeyDownKeyCode = null; addListener(el, "keydown", function(e) { lastKeyDownKeyCode = e.keyCode; }); addListener(el, "keypress", function(e) { return normalizeCommandKeys(callback, e, lastKeyDownKeyCode); }); } else { var lastDefaultPrevented = null; addListener(el, "keydown", function(e) { pressedKeys[e.keyCode] = true; var result = normalizeCommandKeys(callback, e, e.keyCode); lastDefaultPrevented = e.defaultPrevented; return result; }); addListener(el, "keypress", function(e) { if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) { exports.stopEvent(e); lastDefaultPrevented = null; } }); addListener(el, "keyup", function(e) { pressedKeys[e.keyCode] = null; }); if (!pressedKeys) { pressedKeys = Object.create(null); addListener(window, "focus", function(e) { pressedKeys = Object.create(null); }); } } }; if (window.postMessage && !useragent.isOldIE) { var postMessageId = 1; exports.nextTick = function(callback, win) { win = win || window; var messageName = "zero-timeout-message-" + postMessageId; exports.addListener(win, "message", function listener(e) { if (e.data == messageName) { exports.stopPropagation(e); exports.removeListener(win, "message", listener); callback(); } }); win.postMessage(messageName, "*"); }; } exports.nextFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame; if (exports.nextFrame) exports.nextFrame = exports.nextFrame.bind(window); else exports.nextFrame = function(callback) { setTimeout(callback, 17); }; }); ace.define("ace/lib/lang",["require","exports","module"], function(require, exports, module) { "use strict"; exports.last = function(a) { return a[a.length - 1]; }; exports.stringReverse = function(string) { return string.split("").reverse().join(""); }; exports.stringRepeat = function (string, count) { var result = ''; while (count > 0) { if (count & 1) result += string; if (count >>= 1) string += string; } return result; }; var trimBeginRegexp = /^\s\s*/; var trimEndRegexp = /\s\s*$/; exports.stringTrimLeft = function (string) { return string.replace(trimBeginRegexp, ''); }; exports.stringTrimRight = function (string) { return string.replace(trimEndRegexp, ''); }; exports.copyObject = function(obj) { var copy = {}; for (var key in obj) { copy[key] = obj[key]; } return copy; }; exports.copyArray = function(array){ var copy = []; for (var i=0, l=array.length; i 1); return ev.preventDefault(); }; this.startSelect = function(pos, waitForClickSelection) { pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y); var editor = this.editor; if (this.mousedownEvent.getShiftKey()) editor.selection.selectToPosition(pos); else if (!waitForClickSelection) editor.selection.moveToPosition(pos); if (!waitForClickSelection) this.select(); if (editor.renderer.scroller.setCapture) { editor.renderer.scroller.setCapture(); } editor.setStyle("ace_selecting"); this.setState("select"); }; this.select = function() { var anchor, editor = this.editor; var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y); if (this.$clickSelection) { var cmp = this.$clickSelection.comparePoint(cursor); if (cmp == -1) { anchor = this.$clickSelection.end; } else if (cmp == 1) { anchor = this.$clickSelection.start; } else { var orientedRange = calcRangeOrientation(this.$clickSelection, cursor); cursor = orientedRange.cursor; anchor = orientedRange.anchor; } editor.selection.setSelectionAnchor(anchor.row, anchor.column); } editor.selection.selectToPosition(cursor); editor.renderer.scrollCursorIntoView(); }; this.extendSelectionBy = function(unitName) { var anchor, editor = this.editor; var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y); var range = editor.selection[unitName](cursor.row, cursor.column); if (this.$clickSelection) { var cmpStart = this.$clickSelection.comparePoint(range.start); var cmpEnd = this.$clickSelection.comparePoint(range.end); if (cmpStart == -1 && cmpEnd <= 0) { anchor = this.$clickSelection.end; if (range.end.row != cursor.row || range.end.column != cursor.column) cursor = range.start; } else if (cmpEnd == 1 && cmpStart >= 0) { anchor = this.$clickSelection.start; if (range.start.row != cursor.row || range.start.column != cursor.column) cursor = range.end; } else if (cmpStart == -1 && cmpEnd == 1) { cursor = range.end; anchor = range.start; } else { var orientedRange = calcRangeOrientation(this.$clickSelection, cursor); cursor = orientedRange.cursor; anchor = orientedRange.anchor; } editor.selection.setSelectionAnchor(anchor.row, anchor.column); } editor.selection.selectToPosition(cursor); editor.renderer.scrollCursorIntoView(); }; this.selectEnd = this.selectAllEnd = this.selectByWordsEnd = this.selectByLinesEnd = function() { this.$clickSelection = null; this.editor.unsetStyle("ace_selecting"); if (this.editor.renderer.scroller.releaseCapture) { this.editor.renderer.scroller.releaseCapture(); } }; this.focusWait = function() { var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); var time = Date.now(); if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout) this.startSelect(this.mousedownEvent.getDocumentPosition()); }; this.onDoubleClick = function(ev) { var pos = ev.getDocumentPosition(); var editor = this.editor; var session = editor.session; var range = session.getBracketRange(pos); if (range) { if (range.isEmpty()) { range.start.column--; range.end.column++; } this.setState("select"); } else { range = editor.selection.getWordRange(pos.row, pos.column); this.setState("selectByWords"); } this.$clickSelection = range; this.select(); }; this.onTripleClick = function(ev) { var pos = ev.getDocumentPosition(); var editor = this.editor; this.setState("selectByLines"); var range = editor.getSelectionRange(); if (range.isMultiLine() && range.contains(pos.row, pos.column)) { this.$clickSelection = editor.selection.getLineRange(range.start.row); this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end; } else { this.$clickSelection = editor.selection.getLineRange(pos.row); } this.select(); }; this.onQuadClick = function(ev) { var editor = this.editor; editor.selectAll(); this.$clickSelection = editor.getSelectionRange(); this.setState("selectAll"); }; this.onMouseWheel = function(ev) { if (ev.getAccelKey()) return; if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) { ev.wheelX = ev.wheelY; ev.wheelY = 0; } var t = ev.domEvent.timeStamp; var dt = t - (this.$lastScrollTime||0); var editor = this.editor; var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); if (isScrolable || dt < 200) { this.$lastScrollTime = t; editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); return ev.stop(); } }; }).call(DefaultHandlers.prototype); exports.DefaultHandlers = DefaultHandlers; function calcDistance(ax, ay, bx, by) { return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); } function calcRangeOrientation(range, cursor) { if (range.start.row == range.end.row) var cmp = 2 * cursor.column - range.start.column - range.end.column; else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column) var cmp = cursor.column - 4; else var cmp = 2 * cursor.row - range.start.row - range.end.row; if (cmp < 0) return {cursor: range.start, anchor: range.end}; else return {cursor: range.end, anchor: range.start}; } }); ace.define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var dom = require("./lib/dom"); function Tooltip (parentNode) { this.isOpen = false; this.$element = null; this.$parentNode = parentNode; } (function() { this.$init = function() { this.$element = dom.createElement("div"); this.$element.className = "ace_tooltip"; this.$element.style.display = "none"; this.$parentNode.appendChild(this.$element); return this.$element; }; this.getElement = function() { return this.$element || this.$init(); }; this.setText = function(text) { dom.setInnerText(this.getElement(), text); }; this.setHtml = function(html) { this.getElement().innerHTML = html; }; this.setPosition = function(x, y) { this.getElement().style.left = x + "px"; this.getElement().style.top = y + "px"; }; this.setClassName = function(className) { dom.addCssClass(this.getElement(), className); }; this.show = function(text, x, y) { if (text != null) this.setText(text); if (x != null && y != null) this.setPosition(x, y); if (!this.isOpen) { this.getElement().style.display = "block"; this.isOpen = true; } }; this.hide = function() { if (this.isOpen) { this.getElement().style.display = "none"; this.isOpen = false; } }; this.getHeight = function() { return this.getElement().offsetHeight; }; this.getWidth = function() { return this.getElement().offsetWidth; }; }).call(Tooltip.prototype); exports.Tooltip = Tooltip; }); ace.define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"], function(require, exports, module) { "use strict"; var dom = require("../lib/dom"); var oop = require("../lib/oop"); var event = require("../lib/event"); var Tooltip = require("../tooltip").Tooltip; function GutterHandler(mouseHandler) { var editor = mouseHandler.editor; var gutter = editor.renderer.$gutterLayer; var tooltip = new GutterTooltip(editor.container); mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) { if (!editor.isFocused() || e.getButton() != 0) return; var gutterRegion = gutter.getRegion(e); if (gutterRegion == "foldWidgets") return; var row = e.getDocumentPosition().row; var selection = editor.session.selection; if (e.getShiftKey()) selection.selectTo(row, 0); else { if (e.domEvent.detail == 2) { editor.selectAll(); return e.preventDefault(); } mouseHandler.$clickSelection = editor.selection.getLineRange(row); } mouseHandler.setState("selectByLines"); mouseHandler.captureMouse(e); return e.preventDefault(); }); var tooltipTimeout, mouseEvent, tooltipAnnotation; function showTooltip() { var row = mouseEvent.getDocumentPosition().row; var annotation = gutter.$annotations[row]; if (!annotation) return hideTooltip(); var maxRow = editor.session.getLength(); if (row == maxRow) { var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row; var pos = mouseEvent.$pos; if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column)) return hideTooltip(); } if (tooltipAnnotation == annotation) return; tooltipAnnotation = annotation.text.join("
"); tooltip.setHtml(tooltipAnnotation); tooltip.show(); editor.on("mousewheel", hideTooltip); if (mouseHandler.$tooltipFollowsMouse) { moveTooltip(mouseEvent); } else { var gutterElement = gutter.$cells[editor.session.documentToScreenRow(row, 0)].element; var rect = gutterElement.getBoundingClientRect(); var style = tooltip.getElement().style; style.left = rect.right + "px"; style.top = rect.bottom + "px"; } } function hideTooltip() { if (tooltipTimeout) tooltipTimeout = clearTimeout(tooltipTimeout); if (tooltipAnnotation) { tooltip.hide(); tooltipAnnotation = null; editor.removeEventListener("mousewheel", hideTooltip); } } function moveTooltip(e) { tooltip.setPosition(e.x, e.y); } mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) { var target = e.domEvent.target || e.domEvent.srcElement; if (dom.hasCssClass(target, "ace_fold-widget")) return hideTooltip(); if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse) moveTooltip(e); mouseEvent = e; if (tooltipTimeout) return; tooltipTimeout = setTimeout(function() { tooltipTimeout = null; if (mouseEvent && !mouseHandler.isMousePressed) showTooltip(); else hideTooltip(); }, 50); }); event.addListener(editor.renderer.$gutter, "mouseout", function(e) { mouseEvent = null; if (!tooltipAnnotation || tooltipTimeout) return; tooltipTimeout = setTimeout(function() { tooltipTimeout = null; hideTooltip(); }, 50); }); editor.on("changeSession", hideTooltip); } function GutterTooltip(parentNode) { Tooltip.call(this, parentNode); } oop.inherits(GutterTooltip, Tooltip); (function(){ this.setPosition = function(x, y) { var windowWidth = window.innerWidth || document.documentElement.clientWidth; var windowHeight = window.innerHeight || document.documentElement.clientHeight; var width = this.getWidth(); var height = this.getHeight(); x += 15; y += 15; if (x + width > windowWidth) { x -= (x + width) - windowWidth; } if (y + height > windowHeight) { y -= 20 + height; } Tooltip.prototype.setPosition.call(this, x, y); }; }).call(GutterTooltip.prototype); exports.GutterHandler = GutterHandler; }); ace.define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(require, exports, module) { "use strict"; var event = require("../lib/event"); var useragent = require("../lib/useragent"); var MouseEvent = exports.MouseEvent = function(domEvent, editor) { this.domEvent = domEvent; this.editor = editor; this.x = this.clientX = domEvent.clientX; this.y = this.clientY = domEvent.clientY; this.$pos = null; this.$inSelection = null; this.propagationStopped = false; this.defaultPrevented = false; }; (function() { this.stopPropagation = function() { event.stopPropagation(this.domEvent); this.propagationStopped = true; }; this.preventDefault = function() { event.preventDefault(this.domEvent); this.defaultPrevented = true; }; this.stop = function() { this.stopPropagation(); this.preventDefault(); }; this.getDocumentPosition = function() { if (this.$pos) return this.$pos; this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY); return this.$pos; }; this.inSelection = function() { if (this.$inSelection !== null) return this.$inSelection; var editor = this.editor; var selectionRange = editor.getSelectionRange(); if (selectionRange.isEmpty()) this.$inSelection = false; else { var pos = this.getDocumentPosition(); this.$inSelection = selectionRange.contains(pos.row, pos.column); } return this.$inSelection; }; this.getButton = function() { return event.getButton(this.domEvent); }; this.getShiftKey = function() { return this.domEvent.shiftKey; }; this.getAccelKey = useragent.isMac ? function() { return this.domEvent.metaKey; } : function() { return this.domEvent.ctrlKey; }; }).call(MouseEvent.prototype); }); ace.define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(require, exports, module) { "use strict"; var dom = require("../lib/dom"); var event = require("../lib/event"); var useragent = require("../lib/useragent"); var AUTOSCROLL_DELAY = 200; var SCROLL_CURSOR_DELAY = 200; var SCROLL_CURSOR_HYSTERESIS = 5; function DragdropHandler(mouseHandler) { var editor = mouseHandler.editor; var blankImage = dom.createElement("img"); blankImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; if (useragent.isOpera) blankImage.style.cssText = "width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;"; var exports = ["dragWait", "dragWaitEnd", "startDrag", "dragReadyEnd", "onMouseDrag"]; exports.forEach(function(x) { mouseHandler[x] = this[x]; }, this); editor.addEventListener("mousedown", this.onMouseDown.bind(mouseHandler)); var mouseTarget = editor.container; var dragSelectionMarker, x, y; var timerId, range; var dragCursor, counter = 0; var dragOperation; var isInternal; var autoScrollStartTime; var cursorMovedTime; var cursorPointOnCaretMoved; this.onDragStart = function(e) { if (this.cancelDrag || !mouseTarget.draggable) { var self = this; setTimeout(function(){ self.startSelect(); self.captureMouse(e); }, 0); return e.preventDefault(); } range = editor.getSelectionRange(); var dataTransfer = e.dataTransfer; dataTransfer.effectAllowed = editor.getReadOnly() ? "copy" : "copyMove"; if (useragent.isOpera) { editor.container.appendChild(blankImage); blankImage.scrollTop = 0; } dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0); if (useragent.isOpera) { editor.container.removeChild(blankImage); } dataTransfer.clearData(); dataTransfer.setData("Text", editor.session.getTextRange()); isInternal = true; this.setState("drag"); }; this.onDragEnd = function(e) { mouseTarget.draggable = false; isInternal = false; this.setState(null); if (!editor.getReadOnly()) { var dropEffect = e.dataTransfer.dropEffect; if (!dragOperation && dropEffect == "move") editor.session.remove(editor.getSelectionRange()); editor.renderer.$cursorLayer.setBlinking(true); } this.editor.unsetStyle("ace_dragging"); this.editor.renderer.setCursorStyle(""); }; this.onDragEnter = function(e) { if (editor.getReadOnly() || !canAccept(e.dataTransfer)) return; x = e.clientX; y = e.clientY; if (!dragSelectionMarker) addDragMarker(); counter++; e.dataTransfer.dropEffect = dragOperation = getDropEffect(e); return event.preventDefault(e); }; this.onDragOver = function(e) { if (editor.getReadOnly() || !canAccept(e.dataTransfer)) return; x = e.clientX; y = e.clientY; if (!dragSelectionMarker) { addDragMarker(); counter++; } if (onMouseMoveTimer !== null) onMouseMoveTimer = null; e.dataTransfer.dropEffect = dragOperation = getDropEffect(e); return event.preventDefault(e); }; this.onDragLeave = function(e) { counter--; if (counter <= 0 && dragSelectionMarker) { clearDragMarker(); dragOperation = null; return event.preventDefault(e); } }; this.onDrop = function(e) { if (!dragCursor) return; var dataTransfer = e.dataTransfer; if (isInternal) { switch (dragOperation) { case "move": if (range.contains(dragCursor.row, dragCursor.column)) { range = { start: dragCursor, end: dragCursor }; } else { range = editor.moveText(range, dragCursor); } break; case "copy": range = editor.moveText(range, dragCursor, true); break; } } else { var dropData = dataTransfer.getData('Text'); range = { start: dragCursor, end: editor.session.insert(dragCursor, dropData) }; editor.focus(); dragOperation = null; } clearDragMarker(); return event.preventDefault(e); }; event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler)); event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler)); event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler)); event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler)); event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler)); event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler)); function scrollCursorIntoView(cursor, prevCursor) { var now = Date.now(); var vMovement = !prevCursor || cursor.row != prevCursor.row; var hMovement = !prevCursor || cursor.column != prevCursor.column; if (!cursorMovedTime || vMovement || hMovement) { editor.$blockScrolling += 1; editor.moveCursorToPosition(cursor); editor.$blockScrolling -= 1; cursorMovedTime = now; cursorPointOnCaretMoved = {x: x, y: y}; } else { var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y); if (distance > SCROLL_CURSOR_HYSTERESIS) { cursorMovedTime = null; } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) { editor.renderer.scrollCursorIntoView(); cursorMovedTime = null; } } } function autoScroll(cursor, prevCursor) { var now = Date.now(); var lineHeight = editor.renderer.layerConfig.lineHeight; var characterWidth = editor.renderer.layerConfig.characterWidth; var editorRect = editor.renderer.scroller.getBoundingClientRect(); var offsets = { x: { left: x - editorRect.left, right: editorRect.right - x }, y: { top: y - editorRect.top, bottom: editorRect.bottom - y } }; var nearestXOffset = Math.min(offsets.x.left, offsets.x.right); var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom); var scrollCursor = {row: cursor.row, column: cursor.column}; if (nearestXOffset / characterWidth <= 2) { scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2); } if (nearestYOffset / lineHeight <= 1) { scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1); } var vScroll = cursor.row != scrollCursor.row; var hScroll = cursor.column != scrollCursor.column; var vMovement = !prevCursor || cursor.row != prevCursor.row; if (vScroll || (hScroll && !vMovement)) { if (!autoScrollStartTime) autoScrollStartTime = now; else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY) editor.renderer.scrollCursorIntoView(scrollCursor); } else { autoScrollStartTime = null; } } function onDragInterval() { var prevCursor = dragCursor; dragCursor = editor.renderer.screenToTextCoordinates(x, y); scrollCursorIntoView(dragCursor, prevCursor); autoScroll(dragCursor, prevCursor); } function addDragMarker() { range = editor.selection.toOrientedRange(); dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle()); editor.clearSelection(); if (editor.isFocused()) editor.renderer.$cursorLayer.setBlinking(false); clearInterval(timerId); onDragInterval(); timerId = setInterval(onDragInterval, 20); counter = 0; event.addListener(document, "mousemove", onMouseMove); } function clearDragMarker() { clearInterval(timerId); editor.session.removeMarker(dragSelectionMarker); dragSelectionMarker = null; editor.$blockScrolling += 1; editor.selection.fromOrientedRange(range); editor.$blockScrolling -= 1; if (editor.isFocused() && !isInternal) editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly()); range = null; dragCursor = null; counter = 0; autoScrollStartTime = null; cursorMovedTime = null; event.removeListener(document, "mousemove", onMouseMove); } var onMouseMoveTimer = null; function onMouseMove() { if (onMouseMoveTimer == null) { onMouseMoveTimer = setTimeout(function() { if (onMouseMoveTimer != null && dragSelectionMarker) clearDragMarker(); }, 20); } } function canAccept(dataTransfer) { var types = dataTransfer.types; return !types || Array.prototype.some.call(types, function(type) { return type == 'text/plain' || type == 'Text'; }); } function getDropEffect(e) { var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized']; var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized']; var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey; var effectAllowed = "uninitialized"; try { effectAllowed = e.dataTransfer.effectAllowed.toLowerCase(); } catch (e) {} var dropEffect = "none"; if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0) dropEffect = "copy"; else if (moveAllowed.indexOf(effectAllowed) >= 0) dropEffect = "move"; else if (copyAllowed.indexOf(effectAllowed) >= 0) dropEffect = "copy"; return dropEffect; } } (function() { this.dragWait = function() { var interval = Date.now() - this.mousedownEvent.time; if (interval > this.editor.getDragDelay()) this.startDrag(); }; this.dragWaitEnd = function() { var target = this.editor.container; target.draggable = false; this.startSelect(this.mousedownEvent.getDocumentPosition()); this.selectEnd(); }; this.dragReadyEnd = function(e) { this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()); this.editor.unsetStyle("ace_dragging"); this.editor.renderer.setCursorStyle(""); this.dragWaitEnd(); }; this.startDrag = function(){ this.cancelDrag = false; var editor = this.editor; var target = editor.container; target.draggable = true; editor.renderer.$cursorLayer.setBlinking(false); editor.setStyle("ace_dragging"); var cursorStyle = useragent.isWin ? "default" : "move"; editor.renderer.setCursorStyle(cursorStyle); this.setState("dragReady"); }; this.onMouseDrag = function(e) { var target = this.editor.container; if (useragent.isIE && this.state == "dragReady") { var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); if (distance > 3) target.dragDrop(); } if (this.state === "dragWait") { var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); if (distance > 0) { target.draggable = false; this.startSelect(this.mousedownEvent.getDocumentPosition()); } } }; this.onMouseDown = function(e) { if (!this.$dragEnabled) return; this.mousedownEvent = e; var editor = this.editor; var inSelection = e.inSelection(); var button = e.getButton(); var clickCount = e.domEvent.detail || 1; if (clickCount === 1 && button === 0 && inSelection) { if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey())) return; this.mousedownEvent.time = Date.now(); var eventTarget = e.domEvent.target || e.domEvent.srcElement; if ("unselectable" in eventTarget) eventTarget.unselectable = "on"; if (editor.getDragDelay()) { if (useragent.isWebKit) { this.cancelDrag = true; var mouseTarget = editor.container; mouseTarget.draggable = true; } this.setState("dragWait"); } else { this.startDrag(); } this.captureMouse(e, this.onMouseDrag.bind(this)); e.defaultPrevented = true; } }; }).call(DragdropHandler.prototype); function calcDistance(ax, ay, bx, by) { return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); } exports.DragdropHandler = DragdropHandler; }); ace.define("ace/lib/net",["require","exports","module","ace/lib/dom"], function(require, exports, module) { "use strict"; var dom = require("./dom"); exports.get = function (url, callback) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { callback(xhr.responseText); } }; xhr.send(null); }; exports.loadScript = function(path, callback) { var head = dom.getDocumentHead(); var s = document.createElement('script'); s.src = path; head.appendChild(s); s.onload = s.onreadystatechange = function(_, isAbort) { if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") { s = s.onload = s.onreadystatechange = null; if (!isAbort) callback(); } }; }; exports.qualifyURL = function(url) { var a = document.createElement('a'); a.href = url; return a.href; } }); ace.define("ace/lib/event_emitter",["require","exports","module"], function(require, exports, module) { "use strict"; var EventEmitter = {}; var stopPropagation = function() { this.propagationStopped = true; }; var preventDefault = function() { this.defaultPrevented = true; }; EventEmitter._emit = EventEmitter._dispatchEvent = function(eventName, e) { this._eventRegistry || (this._eventRegistry = {}); this._defaultHandlers || (this._defaultHandlers = {}); var listeners = this._eventRegistry[eventName] || []; var defaultHandler = this._defaultHandlers[eventName]; if (!listeners.length && !defaultHandler) return; if (typeof e != "object" || !e) e = {}; if (!e.type) e.type = eventName; if (!e.stopPropagation) e.stopPropagation = stopPropagation; if (!e.preventDefault) e.preventDefault = preventDefault; listeners = listeners.slice(); for (var i=0; i 1) base = parts[parts.length - 2]; var path = options[component + "Path"]; if (path == null) { path = options.basePath; } else if (sep == "/") { component = sep = ""; } if (path && path.slice(-1) != "/") path += "/"; return path + component + sep + base + this.get("suffix"); }; exports.setModuleUrl = function(name, subst) { return options.$moduleUrls[name] = subst; }; exports.$loading = {}; exports.loadModule = function(moduleName, onLoad) { var module, moduleType; if (Array.isArray(moduleName)) { moduleType = moduleName[0]; moduleName = moduleName[1]; } try { module = require(moduleName); } catch (e) {} if (module && !exports.$loading[moduleName]) return onLoad && onLoad(module); if (!exports.$loading[moduleName]) exports.$loading[moduleName] = []; exports.$loading[moduleName].push(onLoad); if (exports.$loading[moduleName].length > 1) return; var afterLoad = function() { require([moduleName], function(module) { exports._emit("load.module", {name: moduleName, module: module}); var listeners = exports.$loading[moduleName]; exports.$loading[moduleName] = null; listeners.forEach(function(onLoad) { onLoad && onLoad(module); }); }); }; if (!exports.get("packaged")) return afterLoad(); net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad); }; init(true);function init(packaged) { options.packaged = packaged || require.packaged || module.packaged || (global.define && define.packaged); if (!global.document) return ""; var scriptOptions = {}; var scriptUrl = ""; var currentScript = (document.currentScript || document._currentScript ); // native or polyfill var currentDocument = currentScript && currentScript.ownerDocument || document; var scripts = currentDocument.getElementsByTagName("script"); for (var i=0; i [" + this.end.row + "/" + this.end.column + "]"); }; this.contains = function(row, column) { return this.compare(row, column) == 0; }; this.compareRange = function(range) { var cmp, end = range.end, start = range.start; cmp = this.compare(end.row, end.column); if (cmp == 1) { cmp = this.compare(start.row, start.column); if (cmp == 1) { return 2; } else if (cmp == 0) { return 1; } else { return 0; } } else if (cmp == -1) { return -2; } else { cmp = this.compare(start.row, start.column); if (cmp == -1) { return -1; } else if (cmp == 1) { return 42; } else { return 0; } } }; this.comparePoint = function(p) { return this.compare(p.row, p.column); }; this.containsRange = function(range) { return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0; }; this.intersects = function(range) { var cmp = this.compareRange(range); return (cmp == -1 || cmp == 0 || cmp == 1); }; this.isEnd = function(row, column) { return this.end.row == row && this.end.column == column; }; this.isStart = function(row, column) { return this.start.row == row && this.start.column == column; }; this.setStart = function(row, column) { if (typeof row == "object") { this.start.column = row.column; this.start.row = row.row; } else { this.start.row = row; this.start.column = column; } }; this.setEnd = function(row, column) { if (typeof row == "object") { this.end.column = row.column; this.end.row = row.row; } else { this.end.row = row; this.end.column = column; } }; this.inside = function(row, column) { if (this.compare(row, column) == 0) { if (this.isEnd(row, column) || this.isStart(row, column)) { return false; } else { return true; } } return false; }; this.insideStart = function(row, column) { if (this.compare(row, column) == 0) { if (this.isEnd(row, column)) { return false; } else { return true; } } return false; }; this.insideEnd = function(row, column) { if (this.compare(row, column) == 0) { if (this.isStart(row, column)) { return false; } else { return true; } } return false; }; this.compare = function(row, column) { if (!this.isMultiLine()) { if (row === this.start.row) { return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0); }; } if (row < this.start.row) return -1; if (row > this.end.row) return 1; if (this.start.row === row) return column >= this.start.column ? 0 : -1; if (this.end.row === row) return column <= this.end.column ? 0 : 1; return 0; }; this.compareStart = function(row, column) { if (this.start.row == row && this.start.column == column) { return -1; } else { return this.compare(row, column); } }; this.compareEnd = function(row, column) { if (this.end.row == row && this.end.column == column) { return 1; } else { return this.compare(row, column); } }; this.compareInside = function(row, column) { if (this.end.row == row && this.end.column == column) { return 1; } else if (this.start.row == row && this.start.column == column) { return -1; } else { return this.compare(row, column); } }; this.clipRows = function(firstRow, lastRow) { if (this.end.row > lastRow) var end = {row: lastRow + 1, column: 0}; else if (this.end.row < firstRow) var end = {row: firstRow, column: 0}; if (this.start.row > lastRow) var start = {row: lastRow + 1, column: 0}; else if (this.start.row < firstRow) var start = {row: firstRow, column: 0}; return Range.fromPoints(start || this.start, end || this.end); }; this.extend = function(row, column) { var cmp = this.compare(row, column); if (cmp == 0) return this; else if (cmp == -1) var start = {row: row, column: column}; else var end = {row: row, column: column}; return Range.fromPoints(start || this.start, end || this.end); }; this.isEmpty = function() { return (this.start.row === this.end.row && this.start.column === this.end.column); }; this.isMultiLine = function() { return (this.start.row !== this.end.row); }; this.clone = function() { return Range.fromPoints(this.start, this.end); }; this.collapseRows = function() { if (this.end.column == 0) return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0) else return new Range(this.start.row, 0, this.end.row, 0) }; this.toScreenRange = function(session) { var screenPosStart = session.documentToScreenPosition(this.start); var screenPosEnd = session.documentToScreenPosition(this.end); return new Range( screenPosStart.row, screenPosStart.column, screenPosEnd.row, screenPosEnd.column ); }; this.moveBy = function(row, column) { this.start.row += row; this.start.column += column; this.end.row += row; this.end.column += column; }; }).call(Range.prototype); Range.fromPoints = function(start, end) { return new Range(start.row, start.column, end.row, end.column); }; Range.comparePoints = comparePoints; Range.comparePoints = function(p1, p2) { return p1.row - p2.row || p1.column - p2.column; }; exports.Range = Range; }); ace.define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var lang = require("./lib/lang"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var Range = require("./range").Range; var Selection = function(session) { this.session = session; this.doc = session.getDocument(); this.clearSelection(); this.lead = this.selectionLead = this.doc.createAnchor(0, 0); this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0); var self = this; this.lead.on("change", function(e) { self._emit("changeCursor"); if (!self.$isEmpty) self._emit("changeSelection"); if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column) self.$desiredColumn = null; }); this.selectionAnchor.on("change", function() { if (!self.$isEmpty) self._emit("changeSelection"); }); }; (function() { oop.implement(this, EventEmitter); this.isEmpty = function() { return (this.$isEmpty || ( this.anchor.row == this.lead.row && this.anchor.column == this.lead.column )); }; this.isMultiLine = function() { if (this.isEmpty()) { return false; } return this.getRange().isMultiLine(); }; this.getCursor = function() { return this.lead.getPosition(); }; this.setSelectionAnchor = function(row, column) { this.anchor.setPosition(row, column); if (this.$isEmpty) { this.$isEmpty = false; this._emit("changeSelection"); } }; this.getSelectionAnchor = function() { if (this.$isEmpty) return this.getSelectionLead(); else return this.anchor.getPosition(); }; this.getSelectionLead = function() { return this.lead.getPosition(); }; this.shiftSelection = function(columns) { if (this.$isEmpty) { this.moveCursorTo(this.lead.row, this.lead.column + columns); return; } var anchor = this.getSelectionAnchor(); var lead = this.getSelectionLead(); var isBackwards = this.isBackwards(); if (!isBackwards || anchor.column !== 0) this.setSelectionAnchor(anchor.row, anchor.column + columns); if (isBackwards || lead.column !== 0) { this.$moveSelection(function() { this.moveCursorTo(lead.row, lead.column + columns); }); } }; this.isBackwards = function() { var anchor = this.anchor; var lead = this.lead; return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column)); }; this.getRange = function() { var anchor = this.anchor; var lead = this.lead; if (this.isEmpty()) return Range.fromPoints(lead, lead); if (this.isBackwards()) { return Range.fromPoints(lead, anchor); } else { return Range.fromPoints(anchor, lead); } }; this.clearSelection = function() { if (!this.$isEmpty) { this.$isEmpty = true; this._emit("changeSelection"); } }; this.selectAll = function() { var lastRow = this.doc.getLength() - 1; this.setSelectionAnchor(0, 0); this.moveCursorTo(lastRow, this.doc.getLine(lastRow).length); }; this.setRange = this.setSelectionRange = function(range, reverse) { if (reverse) { this.setSelectionAnchor(range.end.row, range.end.column); this.selectTo(range.start.row, range.start.column); } else { this.setSelectionAnchor(range.start.row, range.start.column); this.selectTo(range.end.row, range.end.column); } if (this.getRange().isEmpty()) this.$isEmpty = true; this.$desiredColumn = null; }; this.$moveSelection = function(mover) { var lead = this.lead; if (this.$isEmpty) this.setSelectionAnchor(lead.row, lead.column); mover.call(this); }; this.selectTo = function(row, column) { this.$moveSelection(function() { this.moveCursorTo(row, column); }); }; this.selectToPosition = function(pos) { this.$moveSelection(function() { this.moveCursorToPosition(pos); }); }; this.moveTo = function(row, column) { this.clearSelection(); this.moveCursorTo(row, column); }; this.moveToPosition = function(pos) { this.clearSelection(); this.moveCursorToPosition(pos); }; this.selectUp = function() { this.$moveSelection(this.moveCursorUp); }; this.selectDown = function() { this.$moveSelection(this.moveCursorDown); }; this.selectRight = function() { this.$moveSelection(this.moveCursorRight); }; this.selectLeft = function() { this.$moveSelection(this.moveCursorLeft); }; this.selectLineStart = function() { this.$moveSelection(this.moveCursorLineStart); }; this.selectLineEnd = function() { this.$moveSelection(this.moveCursorLineEnd); }; this.selectFileEnd = function() { this.$moveSelection(this.moveCursorFileEnd); }; this.selectFileStart = function() { this.$moveSelection(this.moveCursorFileStart); }; this.selectWordRight = function() { this.$moveSelection(this.moveCursorWordRight); }; this.selectWordLeft = function() { this.$moveSelection(this.moveCursorWordLeft); }; this.getWordRange = function(row, column) { if (typeof column == "undefined") { var cursor = row || this.lead; row = cursor.row; column = cursor.column; } return this.session.getWordRange(row, column); }; this.selectWord = function() { this.setSelectionRange(this.getWordRange()); }; this.selectAWord = function() { var cursor = this.getCursor(); var range = this.session.getAWordRange(cursor.row, cursor.column); this.setSelectionRange(range); }; this.getLineRange = function(row, excludeLastChar) { var rowStart = typeof row == "number" ? row : this.lead.row; var rowEnd; var foldLine = this.session.getFoldLine(rowStart); if (foldLine) { rowStart = foldLine.start.row; rowEnd = foldLine.end.row; } else { rowEnd = rowStart; } if (excludeLastChar === true) return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length); else return new Range(rowStart, 0, rowEnd + 1, 0); }; this.selectLine = function() { this.setSelectionRange(this.getLineRange()); }; this.moveCursorUp = function() { this.moveCursorBy(-1, 0); }; this.moveCursorDown = function() { this.moveCursorBy(1, 0); }; this.moveCursorLeft = function() { var cursor = this.lead.getPosition(), fold; if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) { this.moveCursorTo(fold.start.row, fold.start.column); } else if (cursor.column === 0) { if (cursor.row > 0) { this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length); } } else { var tabSize = this.session.getTabSize(); if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize) this.moveCursorBy(0, -tabSize); else this.moveCursorBy(0, -1); } }; this.moveCursorRight = function() { var cursor = this.lead.getPosition(), fold; if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) { this.moveCursorTo(fold.end.row, fold.end.column); } else if (this.lead.column == this.doc.getLine(this.lead.row).length) { if (this.lead.row < this.doc.getLength() - 1) { this.moveCursorTo(this.lead.row + 1, 0); } } else { var tabSize = this.session.getTabSize(); var cursor = this.lead; if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column, cursor.column+tabSize).split(" ").length-1 == tabSize) this.moveCursorBy(0, tabSize); else this.moveCursorBy(0, 1); } }; this.moveCursorLineStart = function() { var row = this.lead.row; var column = this.lead.column; var screenRow = this.session.documentToScreenRow(row, column); var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0); var beforeCursor = this.session.getDisplayLine( row, null, firstColumnPosition.row, firstColumnPosition.column ); var leadingSpace = beforeCursor.match(/^\s*/); if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart) firstColumnPosition.column += leadingSpace[0].length; this.moveCursorToPosition(firstColumnPosition); }; this.moveCursorLineEnd = function() { var lead = this.lead; var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column); if (this.lead.column == lineEnd.column) { var line = this.session.getLine(lineEnd.row); if (lineEnd.column == line.length) { var textEnd = line.search(/\s+$/); if (textEnd > 0) lineEnd.column = textEnd; } } this.moveCursorTo(lineEnd.row, lineEnd.column); }; this.moveCursorFileEnd = function() { var row = this.doc.getLength() - 1; var column = this.doc.getLine(row).length; this.moveCursorTo(row, column); }; this.moveCursorFileStart = function() { this.moveCursorTo(0, 0); }; this.moveCursorLongWordRight = function() { var row = this.lead.row; var column = this.lead.column; var line = this.doc.getLine(row); var rightOfCursor = line.substring(column); var match; this.session.nonTokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0; var fold = this.session.getFoldAt(row, column, 1); if (fold) { this.moveCursorTo(fold.end.row, fold.end.column); return; } if (match = this.session.nonTokenRe.exec(rightOfCursor)) { column += this.session.nonTokenRe.lastIndex; this.session.nonTokenRe.lastIndex = 0; rightOfCursor = line.substring(column); } if (column >= line.length) { this.moveCursorTo(row, line.length); this.moveCursorRight(); if (row < this.doc.getLength() - 1) this.moveCursorWordRight(); return; } if (match = this.session.tokenRe.exec(rightOfCursor)) { column += this.session.tokenRe.lastIndex; this.session.tokenRe.lastIndex = 0; } this.moveCursorTo(row, column); }; this.moveCursorLongWordLeft = function() { var row = this.lead.row; var column = this.lead.column; var fold; if (fold = this.session.getFoldAt(row, column, -1)) { this.moveCursorTo(fold.start.row, fold.start.column); return; } var str = this.session.getFoldStringAt(row, column, -1); if (str == null) { str = this.doc.getLine(row).substring(0, column); } var leftOfCursor = lang.stringReverse(str); var match; this.session.nonTokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0; if (match = this.session.nonTokenRe.exec(leftOfCursor)) { column -= this.session.nonTokenRe.lastIndex; leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex); this.session.nonTokenRe.lastIndex = 0; } if (column <= 0) { this.moveCursorTo(row, 0); this.moveCursorLeft(); if (row > 0) this.moveCursorWordLeft(); return; } if (match = this.session.tokenRe.exec(leftOfCursor)) { column -= this.session.tokenRe.lastIndex; this.session.tokenRe.lastIndex = 0; } this.moveCursorTo(row, column); }; this.$shortWordEndIndex = function(rightOfCursor) { var match, index = 0, ch; var whitespaceRe = /\s/; var tokenRe = this.session.tokenRe; tokenRe.lastIndex = 0; if (match = this.session.tokenRe.exec(rightOfCursor)) { index = this.session.tokenRe.lastIndex; } else { while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch)) index ++; if (index < 1) { tokenRe.lastIndex = 0; while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) { tokenRe.lastIndex = 0; index ++; if (whitespaceRe.test(ch)) { if (index > 2) { index--; break; } else { while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch)) index ++; if (index > 2) break; } } } } } tokenRe.lastIndex = 0; return index; }; this.moveCursorShortWordRight = function() { var row = this.lead.row; var column = this.lead.column; var line = this.doc.getLine(row); var rightOfCursor = line.substring(column); var fold = this.session.getFoldAt(row, column, 1); if (fold) return this.moveCursorTo(fold.end.row, fold.end.column); if (column == line.length) { var l = this.doc.getLength(); do { row++; rightOfCursor = this.doc.getLine(row); } while (row < l && /^\s*$/.test(rightOfCursor)); if (!/^\s+/.test(rightOfCursor)) rightOfCursor = ""; column = 0; } var index = this.$shortWordEndIndex(rightOfCursor); this.moveCursorTo(row, column + index); }; this.moveCursorShortWordLeft = function() { var row = this.lead.row; var column = this.lead.column; var fold; if (fold = this.session.getFoldAt(row, column, -1)) return this.moveCursorTo(fold.start.row, fold.start.column); var line = this.session.getLine(row).substring(0, column); if (column === 0) { do { row--; line = this.doc.getLine(row); } while (row > 0 && /^\s*$/.test(line)); column = line.length; if (!/\s+$/.test(line)) line = ""; } var leftOfCursor = lang.stringReverse(line); var index = this.$shortWordEndIndex(leftOfCursor); return this.moveCursorTo(row, column - index); }; this.moveCursorWordRight = function() { if (this.session.$selectLongWords) this.moveCursorLongWordRight(); else this.moveCursorShortWordRight(); }; this.moveCursorWordLeft = function() { if (this.session.$selectLongWords) this.moveCursorLongWordLeft(); else this.moveCursorShortWordLeft(); }; this.moveCursorBy = function(rows, chars) { var screenPos = this.session.documentToScreenPosition( this.lead.row, this.lead.column ); if (chars === 0) { if (this.$desiredColumn) screenPos.column = this.$desiredColumn; else this.$desiredColumn = screenPos.column; } var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column); if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) { if (this.session.lineWidgets && this.session.lineWidgets[docPos.row]) docPos.row++; } this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0); }; this.moveCursorToPosition = function(position) { this.moveCursorTo(position.row, position.column); }; this.moveCursorTo = function(row, column, keepDesiredColumn) { var fold = this.session.getFoldAt(row, column, 1); if (fold) { row = fold.start.row; column = fold.start.column; } this.$keepDesiredColumnOnChange = true; this.lead.setPosition(row, column); this.$keepDesiredColumnOnChange = false; if (!keepDesiredColumn) this.$desiredColumn = null; }; this.moveCursorToScreen = function(row, column, keepDesiredColumn) { var pos = this.session.screenToDocumentPosition(row, column); this.moveCursorTo(pos.row, pos.column, keepDesiredColumn); }; this.detach = function() { this.lead.detach(); this.anchor.detach(); this.session = this.doc = null; }; this.fromOrientedRange = function(range) { this.setSelectionRange(range, range.cursor == range.start); this.$desiredColumn = range.desiredColumn || this.$desiredColumn; }; this.toOrientedRange = function(range) { var r = this.getRange(); if (range) { range.start.column = r.start.column; range.start.row = r.start.row; range.end.column = r.end.column; range.end.row = r.end.row; } else { range = r; } range.cursor = this.isBackwards() ? range.start : range.end; range.desiredColumn = this.$desiredColumn; return range; }; this.getRangeOfMovements = function(func) { var start = this.getCursor(); try { func.call(null, this); var end = this.getCursor(); return Range.fromPoints(start,end); } catch(e) { return Range.fromPoints(start,start); } finally { this.moveCursorToPosition(start); } }; this.toJSON = function() { if (this.rangeCount) { var data = this.ranges.map(function(r) { var r1 = r.clone(); r1.isBackwards = r.cursor == r.start; return r1; }); } else { var data = this.getRange(); data.isBackwards = this.isBackwards(); } return data; }; this.fromJSON = function(data) { if (data.start == undefined) { if (this.rangeList) { this.toSingleRange(data[0]); for (var i = data.length; i--; ) { var r = Range.fromPoints(data[i].start, data[i].end); if (data.isBackwards) r.cursor = r.start; this.addRange(r, true); } return; } else data = data[0]; } if (this.rangeList) this.toSingleRange(data); this.setSelectionRange(data, data.isBackwards); }; this.isEqual = function(data) { if ((data.length || this.rangeCount) && data.length != this.rangeCount) return false; if (!data.length || !this.ranges) return this.getRange().isEqual(data); for (var i = this.ranges.length; i--; ) { if (!this.ranges[i].isEqual(data[i])) return false; } return true; }; }).call(Selection.prototype); exports.Selection = Selection; }); ace.define("ace/tokenizer",["require","exports","module"], function(require, exports, module) { "use strict"; var MAX_TOKEN_COUNT = 2000; var Tokenizer = function(rules) { this.states = rules; this.regExps = {}; this.matchMappings = {}; for (var key in this.states) { var state = this.states[key]; var ruleRegExps = []; var matchTotal = 0; var mapping = this.matchMappings[key] = {defaultToken: "text"}; var flag = "g"; var splitterRurles = []; for (var i = 0; i < state.length; i++) { var rule = state[i]; if (rule.defaultToken) mapping.defaultToken = rule.defaultToken; if (rule.caseInsensitive) flag = "gi"; if (rule.regex == null) continue; if (rule.regex instanceof RegExp) rule.regex = rule.regex.toString().slice(1, -1); var adjustedregex = rule.regex; var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2; if (Array.isArray(rule.token)) { if (rule.token.length == 1 || matchcount == 1) { rule.token = rule.token[0]; } else if (matchcount - 1 != rule.token.length) { this.reportError("number of classes and regexp groups doesn't match", { rule: rule, groupCount: matchcount - 1 }); rule.token = rule.token[0]; } else { rule.tokenArray = rule.token; rule.token = null; rule.onMatch = this.$arrayTokens; } } else if (typeof rule.token == "function" && !rule.onMatch) { if (matchcount > 1) rule.onMatch = this.$applyToken; else rule.onMatch = rule.token; } if (matchcount > 1) { if (/\\\d/.test(rule.regex)) { adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) { return "\\" + (parseInt(digit, 10) + matchTotal + 1); }); } else { matchcount = 1; adjustedregex = this.removeCapturingGroups(rule.regex); } if (!rule.splitRegex && typeof rule.token != "string") splitterRurles.push(rule); // flag will be known only at the very end } mapping[matchTotal] = i; matchTotal += matchcount; ruleRegExps.push(adjustedregex); if (!rule.onMatch) rule.onMatch = null; } if (!ruleRegExps.length) { mapping[0] = 0; ruleRegExps.push("$"); } splitterRurles.forEach(function(rule) { rule.splitRegex = this.createSplitterRegexp(rule.regex, flag); }, this); this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag); } }; (function() { this.$setMaxTokenCount = function(m) { MAX_TOKEN_COUNT = m | 0; }; this.$applyToken = function(str) { var values = this.splitRegex.exec(str).slice(1); var types = this.token.apply(this, values); if (typeof types === "string") return [{type: types, value: str}]; var tokens = []; for (var i = 0, l = types.length; i < l; i++) { if (values[i]) tokens[tokens.length] = { type: types[i], value: values[i] }; } return tokens; }, this.$arrayTokens = function(str) { if (!str) return []; var values = this.splitRegex.exec(str); if (!values) return "text"; var tokens = []; var types = this.tokenArray; for (var i = 0, l = types.length; i < l; i++) { if (values[i + 1]) tokens[tokens.length] = { type: types[i], value: values[i + 1] }; } return tokens; }; this.removeCapturingGroups = function(src) { var r = src.replace( /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g, function(x, y) {return y ? "(?:" : x;} ); return r; }; this.createSplitterRegexp = function(src, flag) { if (src.indexOf("(?=") != -1) { var stack = 0; var inChClass = false; var lastCapture = {}; src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function( m, esc, parenOpen, parenClose, square, index ) { if (inChClass) { inChClass = square != "]"; } else if (square) { inChClass = true; } else if (parenClose) { if (stack == lastCapture.stack) { lastCapture.end = index+1; lastCapture.stack = -1; } stack--; } else if (parenOpen) { stack++; if (parenOpen.length != 1) { lastCapture.stack = stack lastCapture.start = index; } } return m; }); if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end))) src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end); } return new RegExp(src, (flag||"").replace("g", "")); }; this.getLineTokens = function(line, startState) { if (startState && typeof startState != "string") { var stack = startState.slice(0); startState = stack[0]; if (startState === "#tmp") { stack.shift() startState = stack.shift() } } else var stack = []; var currentState = startState || "start"; var state = this.states[currentState]; if (!state) { currentState = "start"; state = this.states[currentState]; } var mapping = this.matchMappings[currentState]; var re = this.regExps[currentState]; re.lastIndex = 0; var match, tokens = []; var lastIndex = 0; var matchAttempts = 0; var token = {type: null, value: ""}; while (match = re.exec(line)) { var type = mapping.defaultToken; var rule = null; var value = match[0]; var index = re.lastIndex; if (index - value.length > lastIndex) { var skipped = line.substring(lastIndex, index - value.length); if (token.type == type) { token.value += skipped; } else { if (token.type) tokens.push(token); token = {type: type, value: skipped}; } } for (var i = 0; i < match.length-2; i++) { if (match[i + 1] === undefined) continue; rule = state[mapping[i]]; if (rule.onMatch) type = rule.onMatch(value, currentState, stack); else type = rule.token; if (rule.next) { if (typeof rule.next == "string") { currentState = rule.next; } else { currentState = rule.next(currentState, stack); } state = this.states[currentState]; if (!state) { this.reportError("state doesn't exist", currentState); currentState = "start"; state = this.states[currentState]; } mapping = this.matchMappings[currentState]; lastIndex = index; re = this.regExps[currentState]; re.lastIndex = index; } break; } if (value) { if (typeof type === "string") { if ((!rule || rule.merge !== false) && token.type === type) { token.value += value; } else { if (token.type) tokens.push(token); token = {type: type, value: value}; } } else if (type) { if (token.type) tokens.push(token); token = {type: null, value: ""}; for (var i = 0; i < type.length; i++) tokens.push(type[i]); } } if (lastIndex == line.length) break; lastIndex = index; if (matchAttempts++ > MAX_TOKEN_COUNT) { if (matchAttempts > 2 * line.length) { this.reportError("infinite loop with in ace tokenizer", { startState: startState, line: line }); } while (lastIndex < line.length) { if (token.type) tokens.push(token); token = { value: line.substring(lastIndex, lastIndex += 2000), type: "overflow" }; } currentState = "start"; stack = []; break; } } if (token.type) tokens.push(token); if (stack.length > 1) { if (stack[0] !== currentState) stack.unshift("#tmp", currentState); } return { tokens : tokens, state : stack.length ? stack : currentState }; }; this.reportError = function(msg, data) { var e = new Error(msg); e.data = data; if (typeof console == "object" && console.error) console.error(e); setTimeout(function() { throw e; }); }; }).call(Tokenizer.prototype); exports.Tokenizer = Tokenizer; }); ace.define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"], function(require, exports, module) { "use strict"; var lang = require("../lib/lang"); var TextHighlightRules = function() { this.$rules = { "start" : [{ token : "empty_line", regex : '^$' }, { defaultToken : "text" }] }; }; (function() { this.addRules = function(rules, prefix) { if (!prefix) { for (var key in rules) this.$rules[key] = rules[key]; return; } for (var key in rules) { var state = rules[key]; for (var i = 0; i < state.length; i++) { var rule = state[i]; if (rule.next || rule.onMatch) { if (typeof rule.next != "string") { if (rule.nextState && rule.nextState.indexOf(prefix) !== 0) rule.nextState = prefix + rule.nextState; } else { if (rule.next.indexOf(prefix) !== 0) rule.next = prefix + rule.next; } } } this.$rules[prefix + key] = state; } }; this.getRules = function() { return this.$rules; }; this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) { var embedRules = typeof HighlightRules == "function" ? new HighlightRules().getRules() : HighlightRules; if (states) { for (var i = 0; i < states.length; i++) states[i] = prefix + states[i]; } else { states = []; for (var key in embedRules) states.push(prefix + key); } this.addRules(embedRules, prefix); if (escapeRules) { var addRules = Array.prototype[append ? "push" : "unshift"]; for (var i = 0; i < states.length; i++) addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules)); } if (!this.$embeds) this.$embeds = []; this.$embeds.push(prefix); }; this.getEmbeds = function() { return this.$embeds; }; var pushState = function(currentState, stack) { if (currentState != "start" || stack.length) stack.unshift(this.nextState, currentState); return this.nextState; }; var popState = function(currentState, stack) { stack.shift(); return stack.shift() || "start"; }; this.normalizeRules = function() { var id = 0; var rules = this.$rules; function processState(key) { var state = rules[key]; state.processed = true; for (var i = 0; i < state.length; i++) { var rule = state[i]; if (!rule.regex && rule.start) { rule.regex = rule.start; if (!rule.next) rule.next = []; rule.next.push({ defaultToken: rule.token }, { token: rule.token + ".end", regex: rule.end || rule.start, next: "pop" }); rule.token = rule.token + ".start"; rule.push = true; } var next = rule.next || rule.push; if (next && Array.isArray(next)) { var stateName = rule.stateName; if (!stateName) { stateName = rule.token; if (typeof stateName != "string") stateName = stateName[0] || ""; if (rules[stateName]) stateName += id++; } rules[stateName] = next; rule.next = stateName; processState(stateName); } else if (next == "pop") { rule.next = popState; } if (rule.push) { rule.nextState = rule.next || rule.push; rule.next = pushState; delete rule.push; } if (rule.rules) { for (var r in rule.rules) { if (rules[r]) { if (rules[r].push) rules[r].push.apply(rules[r], rule.rules[r]); } else { rules[r] = rule.rules[r]; } } } if (rule.include || typeof rule == "string") { var includeName = rule.include || rule; var toInsert = rules[includeName]; } else if (Array.isArray(rule)) toInsert = rule; if (toInsert) { var args = [i, 1].concat(toInsert); if (rule.noEscape) args = args.filter(function(x) {return !x.next;}); state.splice.apply(state, args); i--; toInsert = null; } if (rule.keywordMap) { rule.token = this.createKeywordMapper( rule.keywordMap, rule.defaultToken || "text", rule.caseInsensitive ); delete rule.defaultToken; } } } Object.keys(rules).forEach(processState, this); }; this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) { var keywords = Object.create(null); Object.keys(map).forEach(function(className) { var a = map[className]; if (ignoreCase) a = a.toLowerCase(); var list = a.split(splitChar || "|"); for (var i = list.length; i--; ) keywords[list[i]] = className; }); if (Object.getPrototypeOf(keywords)) { keywords.__proto__ = null; } this.$keywordList = Object.keys(keywords); map = null; return ignoreCase ? function(value) {return keywords[value.toLowerCase()] || defaultToken } : function(value) {return keywords[value] || defaultToken }; }; this.getKeywords = function() { return this.$keywords; }; }).call(TextHighlightRules.prototype); exports.TextHighlightRules = TextHighlightRules; }); ace.define("ace/mode/behaviour",["require","exports","module"], function(require, exports, module) { "use strict"; var Behaviour = function() { this.$behaviours = {}; }; (function () { this.add = function (name, action, callback) { switch (undefined) { case this.$behaviours: this.$behaviours = {}; case this.$behaviours[name]: this.$behaviours[name] = {}; } this.$behaviours[name][action] = callback; } this.addBehaviours = function (behaviours) { for (var key in behaviours) { for (var action in behaviours[key]) { this.add(key, action, behaviours[key][action]); } } } this.remove = function (name) { if (this.$behaviours && this.$behaviours[name]) { delete this.$behaviours[name]; } } this.inherit = function (mode, filter) { if (typeof mode === "function") { var behaviours = new mode().getBehaviours(filter); } else { var behaviours = mode.getBehaviours(filter); } this.addBehaviours(behaviours); } this.getBehaviours = function (filter) { if (!filter) { return this.$behaviours; } else { var ret = {} for (var i = 0; i < filter.length; i++) { if (this.$behaviours[filter[i]]) { ret[filter[i]] = this.$behaviours[filter[i]]; } } return ret; } } }).call(Behaviour.prototype); exports.Behaviour = Behaviour; }); ace.define("ace/unicode",["require","exports","module"], function(require, exports, module) { "use strict"; exports.packages = {}; addUnicodePackage({ L: "0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC", Ll: "0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A", Lu: "0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A", Lt: "01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC", Lm: "02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F", Lo: "01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC", M: "0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26", Mn: "0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26", Mc: "0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC", Me: "0488048906DE20DD-20E020E2-20E4A670-A672", N: "0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19", Nd: "0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19", Nl: "16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF", No: "00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835", P: "0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65", Pd: "002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D", Ps: "0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62", Pe: "0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63", Pi: "00AB2018201B201C201F20392E022E042E092E0C2E1C2E20", Pf: "00BB2019201D203A2E032E052E0A2E0D2E1D2E21", Pc: "005F203F20402054FE33FE34FE4D-FE4FFF3F", Po: "0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65", S: "0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD", Sm: "002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC", Sc: "002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6", Sk: "005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3", So: "00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD", Z: "002000A01680180E2000-200A20282029202F205F3000", Zs: "002000A01680180E2000-200A202F205F3000", Zl: "2028", Zp: "2029", C: "0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF", Cc: "0000-001F007F-009F", Cf: "00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB", Co: "E000-F8FF", Cs: "D800-DFFF", Cn: "03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF" }); function addUnicodePackage (pack) { var codePoint = /\w{4}/g; for (var name in pack) exports.packages[name] = pack[name].replace(codePoint, "\\u$&"); }; }); ace.define("ace/token_iterator",["require","exports","module"], function(require, exports, module) { "use strict"; var TokenIterator = function(session, initialRow, initialColumn) { this.$session = session; this.$row = initialRow; this.$rowTokens = session.getTokens(initialRow); var token = session.getTokenAt(initialRow, initialColumn); this.$tokenIndex = token ? token.index : -1; }; (function() { this.stepBackward = function() { this.$tokenIndex -= 1; while (this.$tokenIndex < 0) { this.$row -= 1; if (this.$row < 0) { this.$row = 0; return null; } this.$rowTokens = this.$session.getTokens(this.$row); this.$tokenIndex = this.$rowTokens.length - 1; } return this.$rowTokens[this.$tokenIndex]; }; this.stepForward = function() { this.$tokenIndex += 1; var rowCount; while (this.$tokenIndex >= this.$rowTokens.length) { this.$row += 1; if (!rowCount) rowCount = this.$session.getLength(); if (this.$row >= rowCount) { this.$row = rowCount - 1; return null; } this.$rowTokens = this.$session.getTokens(this.$row); this.$tokenIndex = 0; } return this.$rowTokens[this.$tokenIndex]; }; this.getCurrentToken = function () { return this.$rowTokens[this.$tokenIndex]; }; this.getCurrentTokenRow = function () { return this.$row; }; this.getCurrentTokenColumn = function() { var rowTokens = this.$rowTokens; var tokenIndex = this.$tokenIndex; var column = rowTokens[tokenIndex].start; if (column !== undefined) return column; column = 0; while (tokenIndex > 0) { tokenIndex -= 1; column += rowTokens[tokenIndex].value.length; } return column; }; }).call(TokenIterator.prototype); exports.TokenIterator = TokenIterator; }); ace.define("ace/mode/text",["require","exports","module","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"], function(require, exports, module) { "use strict"; var Tokenizer = require("../tokenizer").Tokenizer; var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var Behaviour = require("./behaviour").Behaviour; var unicode = require("../unicode"); var lang = require("../lib/lang"); var TokenIterator = require("../token_iterator").TokenIterator; var Range = require("../range").Range; var Mode = function() { this.HighlightRules = TextHighlightRules; this.$behaviour = new Behaviour(); }; (function() { this.tokenRe = new RegExp("^[" + unicode.packages.L + unicode.packages.Mn + unicode.packages.Mc + unicode.packages.Nd + unicode.packages.Pc + "\\$_]+", "g" ); this.nonTokenRe = new RegExp("^(?:[^" + unicode.packages.L + unicode.packages.Mn + unicode.packages.Mc + unicode.packages.Nd + unicode.packages.Pc + "\\$_]|\\s])+", "g" ); this.getTokenizer = function() { if (!this.$tokenizer) { this.$highlightRules = this.$highlightRules || new this.HighlightRules(); this.$tokenizer = new Tokenizer(this.$highlightRules.getRules()); } return this.$tokenizer; }; this.lineCommentStart = ""; this.blockComment = ""; this.toggleCommentLines = function(state, session, startRow, endRow) { var doc = session.doc; var ignoreBlankLines = true; var shouldRemove = true; var minIndent = Infinity; var tabSize = session.getTabSize(); var insertAtTabStop = false; if (!this.lineCommentStart) { if (!this.blockComment) return false; var lineCommentStart = this.blockComment.start; var lineCommentEnd = this.blockComment.end; var regexpStart = new RegExp("^(\\s*)(?:" + lang.escapeRegExp(lineCommentStart) + ")"); var regexpEnd = new RegExp("(?:" + lang.escapeRegExp(lineCommentEnd) + ")\\s*$"); var comment = function(line, i) { if (testRemove(line, i)) return; if (!ignoreBlankLines || /\S/.test(line)) { doc.insertInLine({row: i, column: line.length}, lineCommentEnd); doc.insertInLine({row: i, column: minIndent}, lineCommentStart); } }; var uncomment = function(line, i) { var m; if (m = line.match(regexpEnd)) doc.removeInLine(i, line.length - m[0].length, line.length); if (m = line.match(regexpStart)) doc.removeInLine(i, m[1].length, m[0].length); }; var testRemove = function(line, row) { if (regexpStart.test(line)) return true; var tokens = session.getTokens(row); for (var i = 0; i < tokens.length; i++) { if (tokens[i].type === 'comment') return true; } }; } else { if (Array.isArray(this.lineCommentStart)) { var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|"); var lineCommentStart = this.lineCommentStart[0]; } else { var regexpStart = lang.escapeRegExp(this.lineCommentStart); var lineCommentStart = this.lineCommentStart; } regexpStart = new RegExp("^(\\s*)(?:" + regexpStart + ") ?"); insertAtTabStop = session.getUseSoftTabs(); var uncomment = function(line, i) { var m = line.match(regexpStart); if (!m) return; var start = m[1].length, end = m[0].length; if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == " ") end--; doc.removeInLine(i, start, end); }; var commentWithSpace = lineCommentStart + " "; var comment = function(line, i) { if (!ignoreBlankLines || /\S/.test(line)) { if (shouldInsertSpace(line, minIndent, minIndent)) doc.insertInLine({row: i, column: minIndent}, commentWithSpace); else doc.insertInLine({row: i, column: minIndent}, lineCommentStart); } }; var testRemove = function(line, i) { return regexpStart.test(line); }; var shouldInsertSpace = function(line, before, after) { var spaces = 0; while (before-- && line.charAt(before) == " ") spaces++; if (spaces % tabSize != 0) return false; var spaces = 0; while (line.charAt(after++) == " ") spaces++; if (tabSize > 2) return spaces % tabSize != tabSize - 1; else return spaces % tabSize == 0; return true; }; } function iter(fun) { for (var i = startRow; i <= endRow; i++) fun(doc.getLine(i), i); } var minEmptyLength = Infinity; iter(function(line, i) { var indent = line.search(/\S/); if (indent !== -1) { if (indent < minIndent) minIndent = indent; if (shouldRemove && !testRemove(line, i)) shouldRemove = false; } else if (minEmptyLength > line.length) { minEmptyLength = line.length; } }); if (minIndent == Infinity) { minIndent = minEmptyLength; ignoreBlankLines = false; shouldRemove = false; } if (insertAtTabStop && minIndent % tabSize != 0) minIndent = Math.floor(minIndent / tabSize) * tabSize; iter(shouldRemove ? uncomment : comment); }; this.toggleBlockComment = function(state, session, range, cursor) { var comment = this.blockComment; if (!comment) return; if (!comment.start && comment[0]) comment = comment[0]; var iterator = new TokenIterator(session, cursor.row, cursor.column); var token = iterator.getCurrentToken(); var sel = session.selection; var initialRange = session.selection.toOrientedRange(); var startRow, colDiff; if (token && /comment/.test(token.type)) { var startRange, endRange; while (token && /comment/.test(token.type)) { var i = token.value.indexOf(comment.start); if (i != -1) { var row = iterator.getCurrentTokenRow(); var column = iterator.getCurrentTokenColumn() + i; startRange = new Range(row, column, row, column + comment.start.length); break; } token = iterator.stepBackward(); } var iterator = new TokenIterator(session, cursor.row, cursor.column); var token = iterator.getCurrentToken(); while (token && /comment/.test(token.type)) { var i = token.value.indexOf(comment.end); if (i != -1) { var row = iterator.getCurrentTokenRow(); var column = iterator.getCurrentTokenColumn() + i; endRange = new Range(row, column, row, column + comment.end.length); break; } token = iterator.stepForward(); } if (endRange) session.remove(endRange); if (startRange) { session.remove(startRange); startRow = startRange.start.row; colDiff = -comment.start.length; } } else { colDiff = comment.start.length; startRow = range.start.row; session.insert(range.end, comment.end); session.insert(range.start, comment.start); } if (initialRange.start.row == startRow) initialRange.start.column += colDiff; if (initialRange.end.row == startRow) initialRange.end.column += colDiff; session.selection.fromOrientedRange(initialRange); }; this.getNextLineIndent = function(state, line, tab) { return this.$getIndent(line); }; this.checkOutdent = function(state, line, input) { return false; }; this.autoOutdent = function(state, doc, row) { }; this.$getIndent = function(line) { return line.match(/^\s*/)[0]; }; this.createWorker = function(session) { return null; }; this.createModeDelegates = function (mapping) { this.$embeds = []; this.$modes = {}; for (var i in mapping) { if (mapping[i]) { this.$embeds.push(i); this.$modes[i] = new mapping[i](); } } var delegations = ['toggleBlockComment', 'toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent', 'transformAction', 'getCompletions']; for (var i = 0; i < delegations.length; i++) { (function(scope) { var functionName = delegations[i]; var defaultHandler = scope[functionName]; scope[delegations[i]] = function() { return this.$delegator(functionName, arguments, defaultHandler); }; } (this)); } }; this.$delegator = function(method, args, defaultHandler) { var state = args[0]; if (typeof state != "string") state = state[0]; for (var i = 0; i < this.$embeds.length; i++) { if (!this.$modes[this.$embeds[i]]) continue; var split = state.split(this.$embeds[i]); if (!split[0] && split[1]) { args[0] = split[1]; var mode = this.$modes[this.$embeds[i]]; return mode[method].apply(mode, args); } } var ret = defaultHandler.apply(this, args); return defaultHandler ? ret : undefined; }; this.transformAction = function(state, action, editor, session, param) { if (this.$behaviour) { var behaviours = this.$behaviour.getBehaviours(); for (var key in behaviours) { if (behaviours[key][action]) { var ret = behaviours[key][action].apply(this, arguments); if (ret) { return ret; } } } } }; this.getKeywords = function(append) { if (!this.completionKeywords) { var rules = this.$tokenizer.rules; var completionKeywords = []; for (var rule in rules) { var ruleItr = rules[rule]; for (var r = 0, l = ruleItr.length; r < l; r++) { if (typeof ruleItr[r].token === "string") { if (/keyword|support|storage/.test(ruleItr[r].token)) completionKeywords.push(ruleItr[r].regex); } else if (typeof ruleItr[r].token === "object") { for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) { if (/keyword|support|storage/.test(ruleItr[r].token[a])) { var rule = ruleItr[r].regex.match(/\(.+?\)/g)[a]; completionKeywords.push(rule.substr(1, rule.length - 2)); } } } } } this.completionKeywords = completionKeywords; } if (!append) return this.$keywordList; return completionKeywords.concat(this.$keywordList || []); }; this.$createKeywordList = function() { if (!this.$highlightRules) this.getTokenizer(); return this.$keywordList = this.$highlightRules.$keywordList || []; }; this.getCompletions = function(state, session, pos, prefix) { var keywords = this.$keywordList || this.$createKeywordList(); return keywords.map(function(word) { return { name: word, value: word, score: 0, meta: "keyword" }; }); }; this.$id = "ace/mode/text"; }).call(Mode.prototype); exports.Mode = Mode; }); ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var Anchor = exports.Anchor = function(doc, row, column) { this.$onChange = this.onChange.bind(this); this.attach(doc); if (typeof column == "undefined") this.setPosition(row.row, row.column); else this.setPosition(row, column); }; (function() { oop.implement(this, EventEmitter); this.getPosition = function() { return this.$clipPositionToDocument(this.row, this.column); }; this.getDocument = function() { return this.document; }; this.$insertRight = false; 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; var start = range.start; var end = range.end; if (delta.action === "insertText") { if (start.row === row && start.column <= column) { if (start.column === column && this.$insertRight) { } else if (start.row === end.row) { column += end.column - start.column; } else { column -= start.column; row += end.row - start.row; } } else if (start.row !== end.row && start.row < row) { row += end.row - start.row; } } else if (delta.action === "insertLines") { if (start.row === row && column === 0 && this.$insertRight) { } else if (start.row <= row) { row += end.row - start.row; } } else if (delta.action === "removeText") { if (start.row === row && start.column < column) { if (end.column >= column) column = start.column; else column = Math.max(0, column - (end.column - start.column)); } else if (start.row !== end.row && start.row < row) { if (end.row === row) column = Math.max(0, column - end.column) + start.column; row -= (end.row - start.row); } else if (end.row === row) { row -= end.row - start.row; column = Math.max(0, column - end.column) + start.column; } } else if (delta.action == "removeLines") { if (start.row <= row) { if (end.row <= row) row -= end.row - start.row; else { row = 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._signal("change", { old: old, value: pos }); }; this.detach = function() { this.document.removeEventListener("change", this.$onChange); }; this.attach = function(doc) { this.document = doc || this.document; this.document.on("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); }); ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var Range = require("./range").Range; var Anchor = require("./anchor").Anchor; var Document = function(text) { this.$lines = []; if (text.length === 0) { this.$lines = [""]; } else if (Array.isArray(text)) { this._insertLines(0, text); } else { this.insert({row: 0, column:0}, text); } }; (function() { oop.implement(this, EventEmitter); this.setValue = function(text) { var len = this.getLength(); this.remove(new Range(0, 0, len, this.getLine(len-1).length)); this.insert({row: 0, column:0}, text); }; this.getValue = function() { return this.getAllLines().join(this.getNewLineCharacter()); }; this.createAnchor = function(row, column) { return new Anchor(this, row, column); }; if ("aaa".split(/a/).length === 0) this.$split = function(text) { return text.replace(/\r\n|\r/g, "\n").split("\n"); }; else this.$split = function(text) { return text.split(/\r\n|\r|\n/); }; this.$detectNewLine = function(text) { var match = text.match(/^.*?(\r\n|\r|\n)/m); this.$autoNewLine = match ? match[1] : "\n"; this._signal("changeNewLineMode"); }; this.getNewLineCharacter = function() { switch (this.$newLineMode) { case "windows": return "\r\n"; case "unix": return "\n"; default: return this.$autoNewLine || "\n"; } }; this.$autoNewLine = ""; this.$newLineMode = "auto"; this.setNewLineMode = function(newLineMode) { if (this.$newLineMode === newLineMode) return; this.$newLineMode = newLineMode; this._signal("changeNewLineMode"); }; this.getNewLineMode = function() { return this.$newLineMode; }; this.isNewLine = function(text) { return (text == "\r\n" || text == "\r" || text == "\n"); }; this.getLine = function(row) { return this.$lines[row] || ""; }; this.getLines = function(firstRow, lastRow) { return this.$lines.slice(firstRow, lastRow + 1); }; this.getAllLines = function() { return this.getLines(0, this.getLength()); }; this.getLength = function() { return this.$lines.length; }; this.getTextRange = function(range) { if (range.start.row == range.end.row) { return this.getLine(range.start.row) .substring(range.start.column, range.end.column); } var lines = this.getLines(range.start.row, range.end.row); lines[0] = (lines[0] || "").substring(range.start.column); var l = lines.length - 1; if (range.end.row - range.start.row == l) lines[l] = lines[l].substring(0, range.end.column); return lines.join(this.getNewLineCharacter()); }; this.$clipPosition = function(position) { var length = this.getLength(); if (position.row >= length) { position.row = Math.max(0, length - 1); position.column = this.getLine(length-1).length; } else if (position.row < 0) position.row = 0; return position; }; this.insert = function(position, text) { if (!text || text.length === 0) return position; position = this.$clipPosition(position); if (this.getLength() <= 1) this.$detectNewLine(text); var lines = this.$split(text); var firstLine = lines.splice(0, 1)[0]; var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0]; position = this.insertInLine(position, firstLine); if (lastLine !== null) { position = this.insertNewLine(position); // terminate first line position = this._insertLines(position.row, lines); position = this.insertInLine(position, lastLine || ""); } return position; }; this.insertLines = function(row, lines) { if (row >= this.getLength()) return this.insert({row: row, column: 0}, "\n" + lines.join("\n")); return this._insertLines(Math.max(row, 0), lines); }; this._insertLines = function(row, lines) { if (lines.length == 0) return {row: row, column: 0}; while (lines.length > 0xF000) { var end = this._insertLines(row, lines.slice(0, 0xF000)); lines = lines.slice(0xF000); row = end.row; } var args = [row, 0]; args.push.apply(args, lines); this.$lines.splice.apply(this.$lines, args); var range = new Range(row, 0, row + lines.length, 0); var delta = { action: "insertLines", range: range, lines: lines }; this._signal("change", { data: delta }); return range.end; }; this.insertNewLine = function(position) { position = this.$clipPosition(position); var line = this.$lines[position.row] || ""; this.$lines[position.row] = line.substring(0, position.column); this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length)); var end = { row : position.row + 1, column : 0 }; var delta = { action: "insertText", range: Range.fromPoints(position, end), text: this.getNewLineCharacter() }; this._signal("change", { data: delta }); return end; }; this.insertInLine = function(position, text) { if (text.length == 0) return position; var line = this.$lines[position.row] || ""; this.$lines[position.row] = line.substring(0, position.column) + text + line.substring(position.column); var end = { row : position.row, column : position.column + text.length }; var delta = { action: "insertText", range: Range.fromPoints(position, end), text: text }; this._signal("change", { data: delta }); return end; }; this.remove = function(range) { if (!(range instanceof Range)) range = Range.fromPoints(range.start, range.end); range.start = this.$clipPosition(range.start); range.end = this.$clipPosition(range.end); if (range.isEmpty()) return range.start; var firstRow = range.start.row; var lastRow = range.end.row; if (range.isMultiLine()) { var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1; var lastFullRow = lastRow - 1; if (range.end.column > 0) this.removeInLine(lastRow, 0, range.end.column); if (lastFullRow >= firstFullRow) this._removeLines(firstFullRow, lastFullRow); if (firstFullRow != firstRow) { this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length); this.removeNewLine(range.start.row); } } else { this.removeInLine(firstRow, range.start.column, range.end.column); } return range.start; }; this.removeInLine = function(row, startColumn, endColumn) { if (startColumn == endColumn) return; var range = new Range(row, startColumn, row, endColumn); var line = this.getLine(row); var removed = line.substring(startColumn, endColumn); var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length); this.$lines.splice(row, 1, newLine); var delta = { action: "removeText", range: range, text: removed }; this._signal("change", { data: delta }); return range.start; }; this.removeLines = function(firstRow, lastRow) { if (firstRow < 0 || lastRow >= this.getLength()) return this.remove(new Range(firstRow, 0, lastRow + 1, 0)); return this._removeLines(firstRow, lastRow); }; this._removeLines = function(firstRow, lastRow) { var range = new Range(firstRow, 0, lastRow + 1, 0); var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1); var delta = { action: "removeLines", range: range, nl: this.getNewLineCharacter(), lines: removed }; this._signal("change", { data: delta }); return removed; }; this.removeNewLine = function(row) { var firstLine = this.getLine(row); var secondLine = this.getLine(row+1); var range = new Range(row, firstLine.length, row+1, 0); var line = firstLine + secondLine; this.$lines.splice(row, 2, line); var delta = { action: "removeText", range: range, text: this.getNewLineCharacter() }; this._signal("change", { data: delta }); }; this.replace = function(range, text) { if (!(range instanceof Range)) range = Range.fromPoints(range.start, range.end); if (text.length == 0 && range.isEmpty()) return range.start; if (text == this.getTextRange(range)) return range.end; this.remove(range); if (text) { var end = this.insert(range.start, text); } else { end = range.start; } return end; }; this.applyDeltas = function(deltas) { for (var i=0; i=0; i--) { var delta = deltas[i]; var range = Range.fromPoints(delta.range.start, delta.range.end); if (delta.action == "insertLines") this._removeLines(range.start.row, range.end.row - 1); else if (delta.action == "insertText") this.remove(range); else if (delta.action == "removeLines") this._insertLines(range.start.row, delta.lines); else if (delta.action == "removeText") this.insert(range.start, delta.text); } }; this.indexToPosition = function(index, startRow) { var lines = this.$lines || this.getAllLines(); var newlineLength = this.getNewLineCharacter().length; for (var i = startRow || 0, l = lines.length; i < l; i++) { index -= lines[i].length + newlineLength; if (index < 0) return {row: i, column: index + lines[i].length + newlineLength}; } return {row: l-1, column: lines[l-1].length}; }; this.positionToIndex = function(pos, startRow) { var lines = this.$lines || this.getAllLines(); var newlineLength = this.getNewLineCharacter().length; var index = 0; var row = Math.min(pos.row, lines.length); for (var i = startRow || 0; i < row; ++i) index += lines[i].length + newlineLength; return index + pos.column; }; }).call(Document.prototype); exports.Document = Document; }); ace.define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var BackgroundTokenizer = function(tokenizer, editor) { this.running = false; this.lines = []; this.states = []; this.currentLine = 0; this.tokenizer = tokenizer; var self = this; this.$worker = function() { if (!self.running) { return; } var workerStart = new Date(); var currentLine = self.currentLine; var endLine = -1; var doc = self.doc; while (self.lines[currentLine]) currentLine++; var startLine = currentLine; var len = doc.getLength(); var processedLines = 0; self.running = false; while (currentLine < len) { self.$tokenizeRow(currentLine); endLine = currentLine; do { currentLine++; } while (self.lines[currentLine]); processedLines ++; if ((processedLines % 5 === 0) && (new Date() - workerStart) > 20) { self.running = setTimeout(self.$worker, 20); break; } } self.currentLine = currentLine; if (startLine <= endLine) self.fireUpdateEvent(startLine, endLine); }; }; (function(){ oop.implement(this, EventEmitter); this.setTokenizer = function(tokenizer) { this.tokenizer = tokenizer; this.lines = []; this.states = []; this.start(0); }; this.setDocument = function(doc) { this.doc = doc; this.lines = []; this.states = []; this.stop(); }; this.fireUpdateEvent = function(firstRow, lastRow) { var data = { first: firstRow, last: lastRow }; this._signal("update", {data: data}); }; this.start = function(startRow) { this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength()); this.lines.splice(this.currentLine, this.lines.length); this.states.splice(this.currentLine, this.states.length); this.stop(); this.running = setTimeout(this.$worker, 700); }; this.scheduleStart = function() { if (!this.running) this.running = setTimeout(this.$worker, 700); } this.$updateOnChange = function(delta) { var range = delta.range; var startRow = range.start.row; var len = range.end.row - startRow; if (len === 0) { this.lines[startRow] = null; } else if (delta.action == "removeText" || delta.action == "removeLines") { this.lines.splice(startRow, len + 1, null); this.states.splice(startRow, len + 1, null); } else { var args = Array(len + 1); args.unshift(startRow, 1); this.lines.splice.apply(this.lines, args); this.states.splice.apply(this.states, args); } this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength()); this.stop(); }; this.stop = function() { if (this.running) clearTimeout(this.running); this.running = false; }; this.getTokens = function(row) { return this.lines[row] || this.$tokenizeRow(row); }; this.getState = function(row) { if (this.currentLine == row) this.$tokenizeRow(row); return this.states[row] || "start"; }; this.$tokenizeRow = function(row) { var line = this.doc.getLine(row); var state = this.states[row - 1]; var data = this.tokenizer.getLineTokens(line, state, row); if (this.states[row] + "" !== data.state + "") { this.states[row] = data.state; this.lines[row + 1] = null; if (this.currentLine > row + 1) this.currentLine = row + 1; } else if (this.currentLine == row) { this.currentLine = row + 1; } return this.lines[row] = data.tokens; }; }).call(BackgroundTokenizer.prototype); exports.BackgroundTokenizer = BackgroundTokenizer; }); ace.define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(require, exports, module) { "use strict"; var lang = require("./lib/lang"); var oop = require("./lib/oop"); var Range = require("./range").Range; var SearchHighlight = function(regExp, clazz, type) { this.setRegexp(regExp); this.clazz = clazz; this.type = type || "text"; }; (function() { this.MAX_RANGES = 500; this.setRegexp = function(regExp) { if (this.regExp+"" == regExp+"") return; this.regExp = regExp; this.cache = []; }; this.update = function(html, markerLayer, session, config) { if (!this.regExp) return; var start = config.firstRow, end = config.lastRow; for (var i = start; i <= end; i++) { var ranges = this.cache[i]; if (ranges == null) { ranges = lang.getMatchOffsets(session.getLine(i), this.regExp); if (ranges.length > this.MAX_RANGES) ranges = ranges.slice(0, this.MAX_RANGES); ranges = ranges.map(function(match) { return new Range(i, match.offset, i, match.offset + match.length); }); this.cache[i] = ranges.length ? ranges : ""; } for (var j = ranges.length; j --; ) { markerLayer.drawSingleLineMarker( html, ranges[j].toScreenRange(session), this.clazz, config); } } }; }).call(SearchHighlight.prototype); exports.SearchHighlight = SearchHighlight; }); ace.define("ace/edit_session/fold_line",["require","exports","module","ace/range"], function(require, exports, module) { "use strict"; var Range = require("../range").Range; function FoldLine(foldData, folds) { this.foldData = foldData; if (Array.isArray(folds)) { this.folds = folds; } else { folds = this.folds = [ folds ]; } 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; this.end = this.range.end; this.folds.forEach(function(fold) { fold.setFoldLine(this); }, this); } (function() { this.shiftRow = function(shift) { this.start.row += shift; this.end.row += shift; this.folds.forEach(function(fold) { 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"); } this.folds.push(fold); this.folds.sort(function(a, b) { return -a.range.compareEnd(b.start.row, b.start.column); }); if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) { this.end.row = fold.end.row; this.end.column = fold.end.column; } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) { this.start.row = fold.start.row; this.start.column = fold.start.column; } } else if (fold.start.row == this.end.row) { this.folds.push(fold); this.end.row = fold.end.row; this.end.column = fold.end.column; } else if (fold.end.row == this.start.row) { this.folds.unshift(fold); 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"); } 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; if (endRow == null) { endRow = this.end.row; endColumn = this.end.column; } for (var i = 0; i < folds.length; i++) { fold = folds[i]; cmp = fold.range.compareStart(endRow, endColumn); if (cmp == -1) { callback(null, endRow, endColumn, lastEnd, isNewRow); return; } stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow); stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd); if (stop || cmp === 0) { return; } isNewRow = !fold.sameRow; lastEnd = fold.end.column; } callback(null, endRow, endColumn, lastEnd, isNewRow); }; this.getNextFoldTo = function(row, column) { var fold, cmp; for (var i = 0; i < this.folds.length; i++) { fold = this.folds[i]; cmp = fold.range.compareEnd(row, column); if (cmp == -1) { return { fold: fold, kind: "after" }; } else if (cmp === 0) { return { fold: fold, kind: "inside" }; } } return null; }; this.addRemoveChars = function(row, column, len) { var ret = this.getNextFoldTo(row, column), fold, folds; if (ret) { fold = ret.fold; if (ret.kind == "inside" && fold.start.column != column && fold.start.row != row) { window.console && window.console.log(row, column, fold); } else if (fold.start.row == row) { folds = this.folds; var i = folds.indexOf(fold); if (i === 0) { this.start.column += len; } for (i; i < folds.length; i++) { fold = folds[i]; fold.start.column += len; if (!fold.sameRow) { return; } fold.end.column += len; } 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 foldData = this.foldData; var i = folds.indexOf(fold); var foldBefore = folds[i - 1]; this.end.row = foldBefore.end.row; this.end.column = foldBefore.end.column; folds = folds.splice(i, folds.length - i); var newFoldLine = new FoldLine(foldData, folds); foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine); return newFoldLine; }; this.merge = function(foldLineNext) { var folds = foldLineNext.folds; for (var i = 0; i < folds.length; i++) { this.addFold(folds[i]); } var foldData = this.foldData; foldData.splice(foldData.indexOf(foldLineNext), 1); }; this.toString = function() { var ret = [this.range.toString() + ": [" ]; this.folds.forEach(function(fold) { ret.push(" " + fold.toString()); }); ret.push("]"); return ret.join("\n"); }; this.idxToPosition = function(idx) { var lastFoldEndColumn = 0; for (var i = 0; i < this.folds.length; i++) { var fold = this.folds[i]; idx -= fold.start.column - lastFoldEndColumn; if (idx < 0) { return { row: fold.start.row, column: fold.start.column + idx }; } idx -= fold.placeholder.length; if (idx < 0) { return fold.start; } lastFoldEndColumn = fold.end.column; } return { row: this.end.row, column: this.end.column + idx }; }; }).call(FoldLine.prototype); exports.FoldLine = FoldLine; }); ace.define("ace/range_list",["require","exports","module","ace/range"], function(require, exports, module) { "use strict"; var Range = require("./range").Range; var comparePoints = Range.comparePoints; var RangeList = function() { this.ranges = []; }; (function() { this.comparePoints = comparePoints; this.pointIndex = function(pos, excludeEdges, startIndex) { var list = this.ranges; for (var i = startIndex || 0; i < list.length; i++) { var range = list[i]; var cmpEnd = comparePoints(pos, range.end); if (cmpEnd > 0) continue; var cmpStart = comparePoints(pos, range.start); if (cmpEnd === 0) return excludeEdges && cmpStart !== 0 ? -i-2 : i; if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges)) return i; return -i-1; } return -i - 1; }; this.add = function(range) { var excludeEdges = !range.isEmpty(); var startIndex = this.pointIndex(range.start, excludeEdges); if (startIndex < 0) startIndex = -startIndex - 1; var endIndex = this.pointIndex(range.end, excludeEdges, startIndex); if (endIndex < 0) endIndex = -endIndex - 1; else endIndex++; return this.ranges.splice(startIndex, endIndex - startIndex, range); }; this.addList = function(list) { var removed = []; for (var i = list.length; i--; ) { removed.push.call(removed, this.add(list[i])); } return removed; }; this.substractPoint = function(pos) { var i = this.pointIndex(pos); if (i >= 0) return this.ranges.splice(i, 1); }; this.merge = function() { var removed = []; var list = this.ranges; list = list.sort(function(a, b) { return comparePoints(a.start, b.start); }); var next = list[0], range; for (var i = 1; i < list.length; i++) { range = next; next = list[i]; var cmp = comparePoints(range.end, next.start); if (cmp < 0) continue; if (cmp == 0 && !range.isEmpty() && !next.isEmpty()) continue; if (comparePoints(range.end, next.end) < 0) { range.end.row = next.end.row; range.end.column = next.end.column; } list.splice(i, 1); removed.push(next); next = range; i--; } this.ranges = list; return removed; }; this.contains = function(row, column) { return this.pointIndex({row: row, column: column}) >= 0; }; this.containsPoint = function(pos) { return this.pointIndex(pos) >= 0; }; this.rangeAtPoint = function(pos) { var i = this.pointIndex(pos); if (i >= 0) return this.ranges[i]; }; this.clipRows = function(startRow, endRow) { var list = this.ranges; if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow) return []; var startIndex = this.pointIndex({row: startRow, column: 0}); if (startIndex < 0) startIndex = -startIndex - 1; var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex); if (endIndex < 0) endIndex = -endIndex - 1; var clipped = []; for (var i = startIndex; i < endIndex; i++) { clipped.push(list[i]); } return clipped; }; this.removeAll = function() { return this.ranges.splice(0, this.ranges.length); }; this.attach = function(session) { if (this.session) this.detach(); this.session = session; this.onChange = this.$onChange.bind(this); this.session.on('change', this.onChange); }; this.detach = function() { if (!this.session) return; this.session.removeListener('change', this.onChange); this.session = null; }; this.$onChange = function(e) { var changeRange = e.data.range; if (e.data.action[0] == "i"){ var start = changeRange.start; var end = changeRange.end; } else { var end = changeRange.start; var start = changeRange.end; } var startRow = start.row; var endRow = end.row; var lineDif = endRow - startRow; var colDiff = -start.column + end.column; var ranges = this.ranges; for (var i = 0, n = ranges.length; i < n; i++) { var r = ranges[i]; if (r.end.row < startRow) continue; if (r.start.row > startRow) break; if (r.start.row == startRow && r.start.column >= start.column ) { if (r.start.column == start.column && this.$insertRight) { } else { r.start.column += colDiff; r.start.row += lineDif; } } if (r.end.row == startRow && r.end.column >= start.column) { if (r.end.column == start.column && this.$insertRight) { continue; } if (r.end.column == start.column && colDiff > 0 && i < n - 1) { if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column) r.end.column -= colDiff; } r.end.column += colDiff; r.end.row += lineDif; } } if (lineDif != 0 && i < n) { for (; i < n; i++) { var r = ranges[i]; r.start.row += lineDif; r.end.row += lineDif; } } }; }).call(RangeList.prototype); exports.RangeList = RangeList; }); ace.define("ace/edit_session/fold",["require","exports","module","ace/range","ace/range_list","ace/lib/oop"], function(require, exports, module) { "use strict"; var Range = require("../range").Range; var RangeList = require("../range_list").RangeList; var oop = require("../lib/oop") 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 = this.ranges = []; }; oop.inherits(Fold, RangeList); (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()); }); fold.collapseChildren = this.collapseChildren; return fold; }; this.addSubFold = function(fold) { if (this.range.isEqual(fold)) return; if (!this.range.containsRange(fold)) throw new Error("A fold can't intersect already existing fold" + fold.range + this.range); consumeRange(fold, this.start); var row = fold.start.row, column = fold.start.column; for (var i = 0, cmp = -1; i < this.subFolds.length; i++) { cmp = this.subFolds[i].range.compare(row, column); if (cmp != 1) break; } var afterStart = this.subFolds[i]; if (cmp == 0) return afterStart.addSubFold(fold); var row = fold.range.end.row, column = fold.range.end.column; for (var j = i, cmp = -1; j < this.subFolds.length; j++) { cmp = this.subFolds[j].range.compare(row, column); if (cmp != 1) break; } var afterEnd = this.subFolds[j]; if (cmp == 0) throw new Error("A fold can't intersect already existing fold" + fold.range + this.range); var consumedFolds = this.subFolds.splice(i, j - i, fold); fold.setFoldLine(this.foldLine); return fold; }; this.restoreRange = function(range) { return restoreRange(range, this.start); }; }).call(Fold.prototype); function consumePoint(point, anchor) { point.row -= anchor.row; if (point.row == 0) point.column -= anchor.column; } function consumeRange(range, anchor) { consumePoint(range.start, anchor); consumePoint(range.end, anchor); } function restorePoint(point, anchor) { if (point.row == 0) point.column += anchor.column; point.row += anchor.row; } function restoreRange(range, anchor) { restorePoint(range.start, anchor); restorePoint(range.end, anchor); } }); ace.define("ace/edit_session/folding",["require","exports","module","ace/range","ace/edit_session/fold_line","ace/edit_session/fold","ace/token_iterator"], function(require, exports, module) { "use strict"; var Range = require("../range").Range; var FoldLine = require("./fold_line").FoldLine; var Fold = require("./fold").Fold; var TokenIterator = require("../token_iterator").TokenIterator; function Folding() { 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; } } }; this.getFoldsInRange = function(range) { 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) { continue; } else if (cmp == -2) { 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 if (cmp == 42) { break; } foundFolds.push(fold); } } start.column -= 1; end.column += 1; return foundFolds; }; this.getFoldsInRangeList = function(ranges) { if (Array.isArray(ranges)) { var folds = []; ranges.forEach(function(range) { folds = folds.concat(this.getFoldsInRange(range)); }, this); } else { var folds = this.getFoldsInRange(ranges); } return folds; } this.getAllFolds = function() { var folds = []; var foldLines = this.$foldData; for (var i = 0; i < foldLines.length; i++) for (var j = 0; j < foldLines[i].folds.length; j++) folds.push(foldLines[i].folds[j]); return folds; }; this.getFoldStringAt = function(row, column, trim, foldLine) { foldLine = foldLine || this.getFoldLine(row); if (!foldLine) return null; var lastFold = { end: { column: 0 } }; var str, fold; for (var i = 0; i < foldLine.folds.length; i++) { fold = foldLine.folds[i]; var cmp = fold.range.compareEnd(row, column); if (cmp == -1) { 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; }; this.getNextFoldLine = 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.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; }; this.addFold = function(placeholder, range) { var foldData = this.$foldData; var added = false; var fold; if (placeholder instanceof Fold) fold = placeholder; else { fold = new Fold(range, placeholder); fold.collapseChildren = range.collapseChildren; } this.$clipRangeToDocument(fold.range); var startRow = fold.start.row; var startColumn = fold.start.column; var endRow = fold.end.row; var endColumn = fold.end.column; if (!(startRow < endRow || startRow == endRow && startColumn <= endColumn - 2)) throw new Error("The range has to be at least 2 characters width"); var startFold = this.getFoldAt(startRow, startColumn, 1); var endFold = this.getFoldAt(endRow, endColumn, -1); if (startFold && endFold == startFold) return startFold.addSubFold(fold); if (startFold && !startFold.range.isStart(startRow, startColumn)) this.removeFold(startFold); if (endFold && !endFold.range.isEnd(endRow, endColumn)) this.removeFold(endFold); var folds = this.getFoldsInRange(fold.range); if (folds.length > 0) { this.removeFolds(folds); folds.forEach(function(subFold) { fold.addSubFold(subFold); }); } 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) { var foldLineNext = foldData[i + 1]; if (foldLineNext && foldLineNext.start.row == endRow) { 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); else this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row); this.$modified = true; this._emit("changeFold", { data: fold, action: "add" }); 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; var folds = foldLine.folds; if (folds.length == 1) { foldLines.splice(foldLines.indexOf(foldLine), 1); } else 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 (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 if (fold.sameRow) { folds.splice(folds.indexOf(fold), 1); } else { var newFoldLine = foldLine.split(fold.start.row, fold.start.column); folds = newFoldLine.folds; folds.shift(); newFoldLine.start.row = folds[0].start.row; newFoldLine.start.column = folds[0].start.column; } if (!this.$updating) { if (this.$useWrapMode) this.$updateWrapData(startRow, endRow); else this.$updateRowLengthCache(startRow, endRow); } this.$modified = true; this._emit("changeFold", { data: fold, action: "remove" }); }; this.removeFolds = function(folds) { 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(subFold) { fold.restoreRange(subFold); this.addFold(subFold); }, this); if (fold.collapseChildren > 0) { this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1); } fold.subFolds = []; }; this.expandFolds = function(folds) { folds.forEach(function(fold) { this.expandFold(fold); }, this); }; this.unfold = function(location, expandInner) { var range, folds; if (location == null) { range = new Range(0, 0, this.getLength(), 0); expandInner = true; } else if (typeof location == "number") range = new Range(location, 0, location, this.getLine(location).length); else if ("row" in location) range = Range.fromPoints(location, location); else range = location; folds = this.getFoldsInRangeList(range); if (expandInner) { this.removeFolds(folds); } else { var subFolds = folds; while (subFolds.length) { this.expandFolds(subFolds); subFolds = this.getFoldsInRangeList(range); } } if (folds.length) return folds; }; 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.getRowFoldStart = function(docRow, startFoldRow) { var foldLine = this.getFoldLine(docRow, startFoldRow); return foldLine ? foldLine.start.row : docRow; }; this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) { if (startRow == null) startRow = foldLine.start.row; if (startColumn == null) startColumn = 0; if (endRow == null) endRow = foldLine.end.row; if (endColumn == null) endColumn = this.getLine(endRow).length; var doc = this.doc; var textLine = ""; foldLine.walk(function(placeholder, row, column, lastColumn) { if (row < startRow) return; if (row == startRow) { if (column < startColumn) return; lastColumn = Math.max(startColumn, lastColumn); } if (placeholder != null) { textLine += placeholder; } else { textLine += doc.getLine(row).substring(lastColumn, column); } }, 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 fd = []; fd = this.$foldData.map(function(foldLine) { var folds = foldLine.folds.map(function(fold) { return fold.clone(); }); return new FoldLine(fd, folds); }); return fd; }; this.toggleFold = function(tryToUnfold) { var selection = this.selection; var range = selection.getRange(); var fold; var bracketPos; if (range.isEmpty()) { var cursor = range.start; fold = this.getFoldAt(cursor.row, cursor.column); if (fold) { this.expandFold(fold); return; } else if (bracketPos = this.findMatchingBracket(cursor)) { if (range.comparePoint(bracketPos) == 1) { range.end = bracketPos; } else { range.start = bracketPos; range.start.column++; range.end.column--; } } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) { if (range.comparePoint(bracketPos) == 1) range.end = bracketPos; else range.start = bracketPos; range.start.column++; } else { range = this.getCommentFoldRange(cursor.row, cursor.column) || range; } } else { var folds = this.getFoldsInRange(range); if (tryToUnfold && folds.length) { this.expandFolds(folds); return; } else if (folds.length == 1 ) { fold = folds[0]; } } if (!fold) fold = this.getFoldAt(range.start.row, range.start.column); if (fold && fold.range.toString() == range.toString()) { this.expandFold(fold); return; } var placeholder = "..."; if (!range.isMultiLine()) { placeholder = this.getTextRange(range); if(placeholder.length < 4) return; placeholder = placeholder.trim().substring(0, 2) + ".."; } this.addFold(placeholder, range); }; this.getCommentFoldRange = function(row, column, dir) { var iterator = new TokenIterator(this, row, column); var token = iterator.getCurrentToken(); if (token && /^comment|string/.test(token.type)) { var range = new Range(); var re = new RegExp(token.type.replace(/\..*/, "\\.")); if (dir != 1) { do { token = iterator.stepBackward(); } while(token && re.test(token.type)); iterator.stepForward(); } range.start.row = iterator.getCurrentTokenRow(); range.start.column = iterator.getCurrentTokenColumn() + 2; iterator = new TokenIterator(this, row, column); if (dir != -1) { do { token = iterator.stepForward(); } while(token && re.test(token.type)); token = iterator.stepBackward(); } else token = iterator.getCurrentToken(); range.end.row = iterator.getCurrentTokenRow(); range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2; return range; } }; this.foldAll = function(startRow, endRow, depth) { if (depth == undefined) depth = 100000; // JSON.stringify doesn't hanle Infinity var foldWidgets = this.foldWidgets; if (!foldWidgets) return; // mode doesn't support folding endRow = endRow || this.getLength(); startRow = startRow || 0; for (var row = startRow; row < endRow; row++) { if (foldWidgets[row] == null) foldWidgets[row] = this.getFoldWidget(row); if (foldWidgets[row] != "start") continue; var range = this.getFoldWidgetRange(row); if (range && range.isMultiLine() && range.end.row <= endRow && range.start.row >= startRow ) { row = range.end.row; try { var fold = this.addFold("...", range); if (fold) fold.collapseChildren = depth; } catch(e) {} } } }; this.$foldStyles = { "manual": 1, "markbegin": 1, "markbeginend": 1 }; this.$foldStyle = "markbegin"; this.setFoldStyle = function(style) { if (!this.$foldStyles[style]) throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]"); if (this.$foldStyle == style) return; this.$foldStyle = style; if (style == "manual") this.unfold(); var mode = this.$foldMode; this.$setFolding(null); this.$setFolding(mode); }; this.$setFolding = function(foldMode) { if (this.$foldMode == foldMode) return; this.$foldMode = foldMode; this.removeListener('change', this.$updateFoldWidgets); this._emit("changeAnnotation"); if (!foldMode || this.$foldStyle == "manual") { this.foldWidgets = null; return; } this.foldWidgets = []; this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle); this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle); this.$updateFoldWidgets = this.updateFoldWidgets.bind(this); this.on('change', this.$updateFoldWidgets); }; this.getParentFoldRangeData = function (row, ignoreCurrent) { var fw = this.foldWidgets; if (!fw || (ignoreCurrent && fw[row])) return {}; var i = row - 1, firstRange; while (i >= 0) { var c = fw[i]; if (c == null) c = fw[i] = this.getFoldWidget(i); if (c == "start") { var range = this.getFoldWidgetRange(i); if (!firstRange) firstRange = range; if (range && range.end.row >= row) break; } i--; } return { range: i !== -1 && range, firstRange: firstRange }; } this.onFoldWidgetClick = function(row, e) { e = e.domEvent; var options = { children: e.shiftKey, all: e.ctrlKey || e.metaKey, siblings: e.altKey }; var range = this.$toggleFoldWidget(row, options); if (!range) { var el = (e.target || e.srcElement) if (el && /ace_fold-widget/.test(el.className)) el.className += " ace_invalid"; } }; this.$toggleFoldWidget = function(row, options) { if (!this.getFoldWidget) return; var type = this.getFoldWidget(row); var line = this.getLine(row); var dir = type === "end" ? -1 : 1; var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir); if (fold) { if (options.children || options.all) this.removeFold(fold); else this.expandFold(fold); return; } var range = this.getFoldWidgetRange(row, true); if (range && !range.isMultiLine()) { fold = this.getFoldAt(range.start.row, range.start.column, 1); if (fold && range.isEqual(fold.range)) { this.removeFold(fold); return; } } if (options.siblings) { var data = this.getParentFoldRangeData(row); if (data.range) { var startRow = data.range.start.row + 1; var endRow = data.range.end.row; } this.foldAll(startRow, endRow, options.all ? 10000 : 0); } else if (options.children) { endRow = range ? range.end.row : this.getLength(); this.foldAll(row + 1, range.end.row, options.all ? 10000 : 0); } else if (range) { if (options.all) range.collapseChildren = 10000; this.addFold("...", range); } return range; }; this.toggleFoldWidget = function(toggleParent) { var row = this.selection.getCursor().row; row = this.getRowFoldStart(row); var range = this.$toggleFoldWidget(row, {}); if (range) return; var data = this.getParentFoldRangeData(row, true); range = data.range || data.firstRange; if (range) { row = range.start.row; var fold = this.getFoldAt(row, this.getLine(row).length, 1); if (fold) { this.removeFold(fold); } else { this.addFold("...", range); } } }; this.updateFoldWidgets = function(e) { var delta = e.data; var range = delta.range; var firstRow = range.start.row; var len = range.end.row - firstRow; if (len === 0) { this.foldWidgets[firstRow] = null; } else if (delta.action == "removeText" || delta.action == "removeLines") { this.foldWidgets.splice(firstRow, len + 1, null); } else { var args = Array(len + 1); args.unshift(firstRow, 1); this.foldWidgets.splice.apply(this.foldWidgets, args); } }; } exports.Folding = Folding; }); ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"], function(require, exports, module) { "use strict"; var TokenIterator = require("../token_iterator").TokenIterator; var Range = require("../range").Range; function BracketMatch() { this.findMatchingBracket = function(position, chr) { if (position.column == 0) return null; var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1); if (charBeforeCursor == "") return null; var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); if (!match) return null; if (match[1]) return this.$findClosingBracket(match[1], position); else return this.$findOpeningBracket(match[2], position); }; this.getBracketRange = function(pos) { var line = this.getLine(pos.row); var before = true, range; var chr = line.charAt(pos.column-1); var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); if (!match) { chr = line.charAt(pos.column); pos = {row: pos.row, column: pos.column + 1}; match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); before = false; } if (!match) return null; if (match[1]) { var bracketPos = this.$findClosingBracket(match[1], pos); if (!bracketPos) return null; range = Range.fromPoints(pos, bracketPos); if (!before) { range.end.column++; range.start.column--; } range.cursor = range.end; } else { var bracketPos = this.$findOpeningBracket(match[2], pos); if (!bracketPos) return null; range = Range.fromPoints(bracketPos, pos); if (!before) { range.start.column++; range.end.column--; } range.cursor = range.start; } return range; }; this.$brackets = { ")": "(", "(": ")", "]": "[", "[": "]", "{": "}", "}": "{" }; this.$findOpeningBracket = function(bracket, position, typeRe) { var openBracket = this.$brackets[bracket]; var depth = 1; var iterator = new TokenIterator(this, position.row, position.column); var token = iterator.getCurrentToken(); if (!token) token = iterator.stepForward(); if (!token) return; if (!typeRe){ typeRe = new RegExp( "(\\.?" + token.type.replace(".", "\\.").replace("rparen", ".paren") .replace(/\b(?:end|start|begin)\b/, "") + ")+" ); } var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2; var value = token.value; while (true) { while (valueIndex >= 0) { var chr = value.charAt(valueIndex); if (chr == openBracket) { depth -= 1; if (depth == 0) { return {row: iterator.getCurrentTokenRow(), column: valueIndex + iterator.getCurrentTokenColumn()}; } } else if (chr == bracket) { depth += 1; } valueIndex -= 1; } do { token = iterator.stepBackward(); } while (token && !typeRe.test(token.type)); if (token == null) break; value = token.value; valueIndex = value.length - 1; } return null; }; this.$findClosingBracket = function(bracket, position, typeRe) { var closingBracket = this.$brackets[bracket]; var depth = 1; var iterator = new TokenIterator(this, position.row, position.column); var token = iterator.getCurrentToken(); if (!token) token = iterator.stepForward(); if (!token) return; if (!typeRe){ typeRe = new RegExp( "(\\.?" + token.type.replace(".", "\\.").replace("lparen", ".paren") .replace(/\b(?:end|start|begin)\b/, "") + ")+" ); } var valueIndex = position.column - iterator.getCurrentTokenColumn(); while (true) { var value = token.value; var valueLength = value.length; while (valueIndex < valueLength) { var chr = value.charAt(valueIndex); if (chr == closingBracket) { depth -= 1; if (depth == 0) { return {row: iterator.getCurrentTokenRow(), column: valueIndex + iterator.getCurrentTokenColumn()}; } } else if (chr == bracket) { depth += 1; } valueIndex += 1; } do { token = iterator.stepForward(); } while (token && !typeRe.test(token.type)); if (token == null) break; valueIndex = 0; } return null; }; } exports.BracketMatch = BracketMatch; }); ace.define("ace/edit_session",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/config","ace/lib/event_emitter","ace/selection","ace/mode/text","ace/range","ace/document","ace/background_tokenizer","ace/search_highlight","ace/edit_session/folding","ace/edit_session/bracket_match"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var lang = require("./lib/lang"); var config = require("./config"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var Selection = require("./selection").Selection; var TextMode = require("./mode/text").Mode; var Range = require("./range").Range; var Document = require("./document").Document; var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer; var SearchHighlight = require("./search_highlight").SearchHighlight; var EditSession = function(text, mode) { this.$breakpoints = []; this.$decorations = []; this.$frontMarkers = {}; this.$backMarkers = {}; this.$markerId = 1; this.$undoSelect = true; this.$foldData = []; this.$foldData.toString = function() { return this.join("\n"); } this.on("changeFold", this.onChangeFold.bind(this)); this.$onChange = this.onChange.bind(this); if (typeof text != "object" || !text.getLine) text = new Document(text); this.setDocument(text); this.selection = new Selection(this); config.resetOptions(this); this.setMode(mode); config._signal("session", this); }; (function() { oop.implement(this, EventEmitter); this.setDocument = function(doc) { if (this.doc) this.doc.removeListener("change", this.$onChange); this.doc = doc; doc.on("change", this.$onChange); if (this.bgTokenizer) this.bgTokenizer.setDocument(this.getDocument()); this.resetCaches(); }; this.getDocument = function() { return this.doc; }; this.$resetRowCache = function(docRow) { if (!docRow) { this.$docRowCache = []; this.$screenRowCache = []; return; } var l = this.$docRowCache.length; var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1; if (l > i) { this.$docRowCache.splice(i, l); this.$screenRowCache.splice(i, l); } }; this.$getRowCacheIndex = function(cacheArray, val) { var low = 0; var hi = cacheArray.length - 1; while (low <= hi) { var mid = (low + hi) >> 1; var c = cacheArray[mid]; if (val > c) low = mid + 1; else if (val < c) hi = mid - 1; else return mid; } return low -1; }; this.resetCaches = function() { this.$modified = true; this.$wrapData = []; this.$rowLengthCache = []; this.$resetRowCache(0); if (this.bgTokenizer) this.bgTokenizer.start(0); }; this.onChangeFold = function(e) { var fold = e.data; this.$resetRowCache(fold.start.row); }; this.onChange = function(e) { var delta = e.data; this.$modified = true; this.$resetRowCache(delta.range.start.row); var removedFolds = this.$updateInternalDataOnChange(e); if (!this.$fromUndo && this.$undoManager && !delta.ignore) { this.$deltasDoc.push(delta); if (removedFolds && removedFolds.length != 0) { this.$deltasFold.push({ action: "removeFolds", folds: removedFolds }); } this.$informUndoManager.schedule(); } this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta); this._signal("change", e); }; this.setValue = function(text) { this.doc.setValue(text); this.selection.moveTo(0, 0); this.$resetRowCache(0); this.$deltas = []; this.$deltasDoc = []; this.$deltasFold = []; this.setUndoManager(this.$undoManager); this.getUndoManager().reset(); }; this.getValue = this.toString = function() { return this.doc.getValue(); }; this.getSelection = function() { return this.selection; }; this.getState = function(row) { return this.bgTokenizer.getState(row); }; this.getTokens = function(row) { return this.bgTokenizer.getTokens(row); }; this.getTokenAt = function(row, column) { var tokens = this.bgTokenizer.getTokens(row); var token, c = 0; if (column == null) { i = tokens.length - 1; c = this.getLine(row).length; } else { for (var i = 0; i < tokens.length; i++) { c += tokens[i].value.length; if (c >= column) break; } } token = tokens[i]; if (!token) return null; token.index = i; token.start = c - token.value.length; return token; }; this.setUndoManager = function(undoManager) { this.$undoManager = undoManager; this.$deltas = []; this.$deltasDoc = []; this.$deltasFold = []; if (this.$informUndoManager) this.$informUndoManager.cancel(); if (undoManager) { var self = this; this.$syncInformUndoManager = function() { self.$informUndoManager.cancel(); if (self.$deltasFold.length) { self.$deltas.push({ group: "fold", deltas: self.$deltasFold }); self.$deltasFold = []; } if (self.$deltasDoc.length) { self.$deltas.push({ group: "doc", deltas: self.$deltasDoc }); self.$deltasDoc = []; } if (self.$deltas.length > 0) { undoManager.execute({ action: "aceupdate", args: [self.$deltas, self], merge: self.mergeUndoDeltas }); } self.mergeUndoDeltas = false; self.$deltas = []; }; this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager); } }; this.markUndoGroup = function() { if (this.$syncInformUndoManager) this.$syncInformUndoManager(); }; this.$defaultUndoManager = { undo: function() {}, redo: function() {}, reset: function() {} }; this.getUndoManager = function() { return this.$undoManager || this.$defaultUndoManager; }; this.getTabString = function() { if (this.getUseSoftTabs()) { return lang.stringRepeat(" ", this.getTabSize()); } else { return "\t"; } }; this.setUseSoftTabs = function(val) { this.setOption("useSoftTabs", val); }; this.getUseSoftTabs = function() { return this.$useSoftTabs && !this.$mode.$indentWithTabs; }; this.setTabSize = function(tabSize) { this.setOption("tabSize", tabSize); }; this.getTabSize = function() { return this.$tabSize; }; this.isTabStop = function(position) { return this.$useSoftTabs && (position.column % this.$tabSize === 0); }; this.$overwrite = false; this.setOverwrite = function(overwrite) { this.setOption("overwrite", overwrite); }; this.getOverwrite = function() { return this.$overwrite; }; this.toggleOverwrite = function() { this.setOverwrite(!this.$overwrite); }; this.addGutterDecoration = function(row, className) { if (!this.$decorations[row]) this.$decorations[row] = ""; this.$decorations[row] += " " + className; this._signal("changeBreakpoint", {}); }; this.removeGutterDecoration = function(row, className) { this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, ""); this._signal("changeBreakpoint", {}); }; this.getBreakpoints = function() { return this.$breakpoints; }; this.setBreakpoints = function(rows) { this.$breakpoints = []; for (var i=0; i 0) inToken = !!line.charAt(column - 1).match(this.tokenRe); if (!inToken) inToken = !!line.charAt(column).match(this.tokenRe); if (inToken) var re = this.tokenRe; else if (/^\s+$/.test(line.slice(column-1, column+1))) var re = /\s/; else var re = this.nonTokenRe; var start = column; if (start > 0) { do { start--; } while (start >= 0 && line.charAt(start).match(re)); start++; } var end = column; while (end < line.length && line.charAt(end).match(re)) { end++; } return new Range(row, start, row, end); }; this.getAWordRange = function(row, column) { var wordRange = this.getWordRange(row, column); var line = this.getLine(wordRange.end.row); while (line.charAt(wordRange.end.column).match(/[ \t]/)) { wordRange.end.column += 1; } return wordRange; }; this.setNewLineMode = function(newLineMode) { this.doc.setNewLineMode(newLineMode); }; this.getNewLineMode = function() { return this.doc.getNewLineMode(); }; this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); }; this.getUseWorker = function() { return this.$useWorker; }; this.onReloadTokenizer = function(e) { var rows = e.data; this.bgTokenizer.start(rows.first); this._signal("tokenizerUpdate", e); }; this.$modes = {}; this.$mode = null; this.$modeId = null; this.setMode = function(mode, cb) { if (mode && typeof mode === "object") { if (mode.getTokenizer) return this.$onChangeMode(mode); var options = mode; var path = options.path; } else { path = mode || "ace/mode/text"; } if (!this.$modes["ace/mode/text"]) this.$modes["ace/mode/text"] = new TextMode(); if (this.$modes[path] && !options) { this.$onChangeMode(this.$modes[path]); cb && cb(); return; } this.$modeId = path; config.loadModule(["mode", path], function(m) { if (this.$modeId !== path) return cb && cb(); if (this.$modes[path] && !options) return this.$onChangeMode(this.$modes[path]); if (m && m.Mode) { m = new m.Mode(options); if (!options) { this.$modes[path] = m; m.$id = path; } this.$onChangeMode(m); cb && cb(); } }.bind(this)); if (!this.$mode) this.$onChangeMode(this.$modes["ace/mode/text"], true); }; this.$onChangeMode = function(mode, $isPlaceholder) { if (!$isPlaceholder) this.$modeId = mode.$id; if (this.$mode === mode) return; this.$mode = mode; this.$stopWorker(); if (this.$useWorker) this.$startWorker(); var tokenizer = mode.getTokenizer(); if(tokenizer.addEventListener !== undefined) { var onReloadTokenizer = this.onReloadTokenizer.bind(this); tokenizer.addEventListener("update", onReloadTokenizer); } if (!this.bgTokenizer) { this.bgTokenizer = new BackgroundTokenizer(tokenizer); var _self = this; this.bgTokenizer.addEventListener("update", function(e) { _self._signal("tokenizerUpdate", e); }); } else { this.bgTokenizer.setTokenizer(tokenizer); } this.bgTokenizer.setDocument(this.getDocument()); this.tokenRe = mode.tokenRe; this.nonTokenRe = mode.nonTokenRe; if (!$isPlaceholder) { if (mode.attachToSession) mode.attachToSession(this); this.$options.wrapMethod.set.call(this, this.$wrapMethod); this.$setFolding(mode.foldingRules); this.bgTokenizer.start(0); this._emit("changeMode"); } }; this.$stopWorker = function() { if (this.$worker) { this.$worker.terminate(); this.$worker = null; } }; this.$startWorker = function() { try { this.$worker = this.$mode.createWorker(this); } catch (e) { if (typeof console == "object") { console.log("Could not load worker"); console.log(e); } this.$worker = null; } }; this.getMode = function() { return this.$mode; }; this.$scrollTop = 0; this.setScrollTop = function(scrollTop) { if (this.$scrollTop === scrollTop || isNaN(scrollTop)) return; this.$scrollTop = scrollTop; this._signal("changeScrollTop", scrollTop); }; this.getScrollTop = function() { return this.$scrollTop; }; this.$scrollLeft = 0; this.setScrollLeft = function(scrollLeft) { if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft)) return; this.$scrollLeft = scrollLeft; this._signal("changeScrollLeft", scrollLeft); }; this.getScrollLeft = function() { return this.$scrollLeft; }; this.getScreenWidth = function() { this.$computeWidth(); if (this.lineWidgets) return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth); return this.screenWidth; }; this.getLineWidgetMaxWidth = function() { if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth; var width = 0; this.lineWidgets.forEach(function(w) { if (w && w.screenWidth > width) width = w.screenWidth; }); return this.lineWidgetWidth = width; }; this.$computeWidth = function(force) { if (this.$modified || force) { this.$modified = false; if (this.$useWrapMode) return this.screenWidth = this.$wrapLimit; var lines = this.doc.getAllLines(); var cache = this.$rowLengthCache; var longestScreenLine = 0; var foldIndex = 0; var foldLine = this.$foldData[foldIndex]; var foldStart = foldLine ? foldLine.start.row : Infinity; var len = lines.length; for (var i = 0; i < len; i++) { if (i > foldStart) { i = foldLine.end.row + 1; if (i >= len) break; foldLine = this.$foldData[foldIndex++]; foldStart = foldLine ? foldLine.start.row : Infinity; } if (cache[i] == null) cache[i] = this.$getStringScreenWidth(lines[i])[0]; if (cache[i] > longestScreenLine) longestScreenLine = cache[i]; } this.screenWidth = longestScreenLine; } }; this.getLine = function(row) { return this.doc.getLine(row); }; this.getLines = function(firstRow, lastRow) { return this.doc.getLines(firstRow, lastRow); }; this.getLength = function() { return this.doc.getLength(); }; this.getTextRange = function(range) { return this.doc.getTextRange(range || this.selection.getRange()); }; this.insert = function(position, text) { return this.doc.insert(position, text); }; this.remove = function(range) { return this.doc.remove(range); }; this.undoChanges = function(deltas, dontSelect) { if (!deltas.length) return; this.$fromUndo = true; var lastUndoRange = null; for (var i = deltas.length - 1; i != -1; i--) { var delta = deltas[i]; if (delta.group == "doc") { this.doc.revertDeltas(delta.deltas); lastUndoRange = this.$getUndoSelection(delta.deltas, true, lastUndoRange); } else { delta.deltas.forEach(function(foldDelta) { this.addFolds(foldDelta.folds); }, this); } } this.$fromUndo = false; lastUndoRange && this.$undoSelect && !dontSelect && this.selection.setSelectionRange(lastUndoRange); return lastUndoRange; }; this.redoChanges = function(deltas, dontSelect) { if (!deltas.length) return; this.$fromUndo = true; var lastUndoRange = null; for (var i = 0; i < deltas.length; i++) { var delta = deltas[i]; if (delta.group == "doc") { this.doc.applyDeltas(delta.deltas); lastUndoRange = this.$getUndoSelection(delta.deltas, false, lastUndoRange); } } this.$fromUndo = false; lastUndoRange && this.$undoSelect && !dontSelect && this.selection.setSelectionRange(lastUndoRange); return lastUndoRange; }; this.setUndoSelect = function(enable) { this.$undoSelect = enable; }; this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) { function isInsert(delta) { var insert = delta.action === "insertText" || delta.action === "insertLines"; return isUndo ? !insert : insert; } var delta = deltas[0]; var range, point; var lastDeltaIsInsert = false; if (isInsert(delta)) { range = Range.fromPoints(delta.range.start, delta.range.end); lastDeltaIsInsert = true; } else { range = Range.fromPoints(delta.range.start, delta.range.start); lastDeltaIsInsert = false; } for (var i = 1; i < deltas.length; i++) { delta = deltas[i]; if (isInsert(delta)) { point = delta.range.start; if (range.compare(point.row, point.column) == -1) { range.setStart(delta.range.start); } point = delta.range.end; if (range.compare(point.row, point.column) == 1) { range.setEnd(delta.range.end); } lastDeltaIsInsert = true; } else { point = delta.range.start; if (range.compare(point.row, point.column) == -1) { range = Range.fromPoints(delta.range.start, delta.range.start); } lastDeltaIsInsert = false; } } if (lastUndoRange != null) { if (Range.comparePoints(lastUndoRange.start, range.start) === 0) { lastUndoRange.start.column += range.end.column - range.start.column; lastUndoRange.end.column += range.end.column - range.start.column; } var cmp = lastUndoRange.compareRange(range); if (cmp == 1) { range.setStart(lastUndoRange.start); } else if (cmp == -1) { range.setEnd(lastUndoRange.end); } } return range; }; this.replace = function(range, text) { return this.doc.replace(range, text); }; this.moveText = function(fromRange, toPosition, copy) { var text = this.getTextRange(fromRange); var folds = this.getFoldsInRange(fromRange); var toRange = Range.fromPoints(toPosition, toPosition); if (!copy) { this.remove(fromRange); var rowDiff = fromRange.start.row - fromRange.end.row; var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column; if (collDiff) { if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column) toRange.start.column += collDiff; if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column) toRange.end.column += collDiff; } if (rowDiff && toRange.start.row >= fromRange.end.row) { toRange.start.row += rowDiff; toRange.end.row += rowDiff; } } toRange.end = this.insert(toRange.start, text); if (folds.length) { var oldStart = fromRange.start; var newStart = toRange.start; var rowDiff = newStart.row - oldStart.row; var collDiff = newStart.column - oldStart.column; this.addFolds(folds.map(function(x) { x = x.clone(); if (x.start.row == oldStart.row) x.start.column += collDiff; if (x.end.row == oldStart.row) x.end.column += collDiff; x.start.row += rowDiff; x.end.row += rowDiff; return x; })); } return toRange; }; this.indentRows = function(startRow, endRow, indentString) { indentString = indentString.replace(/\t/g, this.getTabString()); for (var row=startRow; row<=endRow; row++) this.insert({row: row, column:0}, indentString); }; this.outdentRows = function (range) { var rowRange = range.collapseRows(); var deleteRange = new Range(0, 0, 0, 0); var size = this.getTabSize(); for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) { var line = this.getLine(i); deleteRange.start.row = i; deleteRange.end.row = i; for (var j = 0; j < size; ++j) if (line.charAt(j) != ' ') break; if (j < size && line.charAt(j) == '\t') { deleteRange.start.column = j; deleteRange.end.column = j + 1; } else { deleteRange.start.column = 0; deleteRange.end.column = j; } this.remove(deleteRange); } }; this.$moveLines = function(firstRow, lastRow, dir) { firstRow = this.getRowFoldStart(firstRow); lastRow = this.getRowFoldEnd(lastRow); if (dir < 0) { var row = this.getRowFoldStart(firstRow + dir); if (row < 0) return 0; var diff = row-firstRow; } else if (dir > 0) { var row = this.getRowFoldEnd(lastRow + dir); if (row > this.doc.getLength()-1) return 0; var diff = row-lastRow; } else { firstRow = this.$clipRowToDocument(firstRow); lastRow = this.$clipRowToDocument(lastRow); var diff = lastRow - firstRow + 1; } var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE); var folds = this.getFoldsInRange(range).map(function(x){ x = x.clone(); x.start.row += diff; x.end.row += diff; return x; }); var lines = dir == 0 ? this.doc.getLines(firstRow, lastRow) : this.doc.removeLines(firstRow, lastRow); this.doc.insertLines(firstRow+diff, lines); folds.length && this.addFolds(folds); return diff; }; this.moveLinesUp = function(firstRow, lastRow) { return this.$moveLines(firstRow, lastRow, -1); }; this.moveLinesDown = function(firstRow, lastRow) { return this.$moveLines(firstRow, lastRow, 1); }; this.duplicateLines = function(firstRow, lastRow) { return this.$moveLines(firstRow, lastRow, 0); }; this.$clipRowToDocument = function(row) { return Math.max(0, Math.min(row, this.doc.getLength()-1)); }; this.$clipColumnToRow = function(row, column) { if (column < 0) return 0; return Math.min(this.doc.getLine(row).length, column); }; this.$clipPositionToDocument = function(row, column) { column = Math.max(0, column); if (row < 0) { row = 0; column = 0; } else { var len = this.doc.getLength(); if (row >= len) { row = len - 1; column = this.doc.getLine(len-1).length; } else { column = Math.min(this.doc.getLine(row).length, column); } } return { row: row, column: column }; }; this.$clipRangeToDocument = function(range) { if (range.start.row < 0) { range.start.row = 0; range.start.column = 0; } else { range.start.column = this.$clipColumnToRow( range.start.row, range.start.column ); } var len = this.doc.getLength() - 1; if (range.end.row > len) { range.end.row = len; range.end.column = this.doc.getLine(len).length; } else { range.end.column = this.$clipColumnToRow( range.end.row, range.end.column ); } return range; }; this.$wrapLimit = 80; this.$useWrapMode = false; this.$wrapLimitRange = { min : null, max : null }; this.setUseWrapMode = function(useWrapMode) { if (useWrapMode != this.$useWrapMode) { this.$useWrapMode = useWrapMode; this.$modified = true; this.$resetRowCache(0); if (useWrapMode) { var len = this.getLength(); this.$wrapData = Array(len); this.$updateWrapData(0, len - 1); } this._signal("changeWrapMode"); } }; this.getUseWrapMode = function() { return this.$useWrapMode; }; this.setWrapLimitRange = function(min, max) { if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) { this.$wrapLimitRange = { min: min, max: max }; this.$modified = true; this._signal("changeWrapMode"); } }; this.adjustWrapLimit = function(desiredLimit, $printMargin) { var limits = this.$wrapLimitRange; if (limits.max < 0) limits = {min: $printMargin, max: $printMargin}; var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max); if (wrapLimit != this.$wrapLimit && wrapLimit > 1) { this.$wrapLimit = wrapLimit; this.$modified = true; if (this.$useWrapMode) { this.$updateWrapData(0, this.getLength() - 1); this.$resetRowCache(0); this._signal("changeWrapLimit"); } return true; } return false; }; this.$constrainWrapLimit = function(wrapLimit, min, max) { if (min) wrapLimit = Math.max(min, wrapLimit); if (max) wrapLimit = Math.min(max, wrapLimit); return wrapLimit; }; this.getWrapLimit = function() { return this.$wrapLimit; }; this.setWrapLimit = function (limit) { this.setWrapLimitRange(limit, limit); }; this.getWrapLimitRange = function() { return { min : this.$wrapLimitRange.min, max : this.$wrapLimitRange.max }; }; this.$updateInternalDataOnChange = function(e) { var useWrapMode = this.$useWrapMode; var len; var action = e.data.action; var firstRow = e.data.range.start.row; var lastRow = e.data.range.end.row; var start = e.data.range.start; var end = e.data.range.end; var removedFolds = null; if (action.indexOf("Lines") != -1) { if (action == "insertLines") { lastRow = firstRow + (e.data.lines.length); } else { lastRow = firstRow; } len = e.data.lines ? e.data.lines.length : lastRow - firstRow; } else { len = lastRow - firstRow; } this.$updating = true; if (len != 0) { if (action.indexOf("remove") != -1) { this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len); var foldLines = this.$foldData; removedFolds = this.getFoldsInRange(e.data.range); this.removeFolds(removedFolds); var foldLine = this.getFoldLine(end.row); var idx = 0; if (foldLine) { foldLine.addRemoveChars(end.row, end.column, start.column - end.column); foldLine.shiftRow(-len); var foldLineBefore = this.getFoldLine(firstRow); if (foldLineBefore && foldLineBefore !== foldLine) { foldLineBefore.merge(foldLine); foldLine = foldLineBefore; } idx = foldLines.indexOf(foldLine) + 1; } for (idx; idx < foldLines.length; idx++) { var foldLine = foldLines[idx]; if (foldLine.start.row >= end.row) { foldLine.shiftRow(-len); } } lastRow = firstRow; } else { var args = Array(len); args.unshift(firstRow, 0); var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache arr.splice.apply(arr, args); var foldLines = this.$foldData; var foldLine = this.getFoldLine(firstRow); var idx = 0; if (foldLine) { var cmp = foldLine.range.compareInside(start.row, start.column); if (cmp == 0) { foldLine = foldLine.split(start.row, start.column); if (foldLine) { foldLine.shiftRow(len); foldLine.addRemoveChars(lastRow, 0, end.column - start.column); } } else if (cmp == -1) { foldLine.addRemoveChars(firstRow, 0, end.column - start.column); foldLine.shiftRow(len); } idx = foldLines.indexOf(foldLine) + 1; } for (idx; idx < foldLines.length; idx++) { var foldLine = foldLines[idx]; if (foldLine.start.row >= firstRow) { foldLine.shiftRow(len); } } } } else { len = Math.abs(e.data.range.start.column - e.data.range.end.column); if (action.indexOf("remove") != -1) { removedFolds = this.getFoldsInRange(e.data.range); this.removeFolds(removedFolds); len = -len; } var foldLine = this.getFoldLine(firstRow); if (foldLine) { foldLine.addRemoveChars(firstRow, start.column, len); } } if (useWrapMode && this.$wrapData.length != this.doc.getLength()) { console.error("doc.getLength() and $wrapData.length have to be the same!"); } this.$updating = false; if (useWrapMode) this.$updateWrapData(firstRow, lastRow); else this.$updateRowLengthCache(firstRow, lastRow); return removedFolds; }; this.$updateRowLengthCache = function(firstRow, lastRow, b) { this.$rowLengthCache[firstRow] = null; this.$rowLengthCache[lastRow] = null; }; this.$updateWrapData = function(firstRow, lastRow) { var lines = this.doc.getAllLines(); var tabSize = this.getTabSize(); var wrapData = this.$wrapData; var wrapLimit = this.$wrapLimit; var tokens; var foldLine; var row = firstRow; lastRow = Math.min(lastRow, lines.length - 1); while (row <= lastRow) { foldLine = this.getFoldLine(row, foldLine); if (!foldLine) { tokens = this.$getDisplayTokens(lines[row]); wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize); row ++; } else { tokens = []; foldLine.walk(function(placeholder, row, column, lastColumn) { var walkTokens; if (placeholder != null) { walkTokens = this.$getDisplayTokens( placeholder, tokens.length); walkTokens[0] = PLACEHOLDER_START; for (var i = 1; i < walkTokens.length; i++) { walkTokens[i] = PLACEHOLDER_BODY; } } else { walkTokens = this.$getDisplayTokens( lines[row].substring(lastColumn, column), tokens.length); } tokens = tokens.concat(walkTokens); }.bind(this), foldLine.end.row, lines[foldLine.end.row].length + 1 ); wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize); row = foldLine.end.row + 1; } } }; var CHAR = 1, CHAR_EXT = 2, PLACEHOLDER_START = 3, PLACEHOLDER_BODY = 4, PUNCTUATION = 9, SPACE = 10, TAB = 11, TAB_SPACE = 12; this.$computeWrapSplits = function(tokens, wrapLimit) { if (tokens.length == 0) { return []; } var splits = []; var displayLength = tokens.length; var lastSplit = 0, lastDocSplit = 0; var isCode = this.$wrapAsCode; function addSplit(screenPos) { var displayed = tokens.slice(lastSplit, screenPos); var len = displayed.length; displayed.join(""). replace(/12/g, function() { len -= 1; }). replace(/2/g, function() { len -= 1; }); lastDocSplit += len; splits.push(lastDocSplit); lastSplit = screenPos; } while (displayLength - lastSplit > wrapLimit) { var split = lastSplit + wrapLimit; if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) { addSplit(split); continue; } if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) { for (split; split != lastSplit - 1; split--) { if (tokens[split] == PLACEHOLDER_START) { break; } } if (split > lastSplit) { addSplit(split); continue; } split = lastSplit + wrapLimit; for (split; split < tokens.length; split++) { if (tokens[split] != PLACEHOLDER_BODY) { break; } } if (split == tokens.length) { break; // Breaks the while-loop. } addSplit(split); continue; } var minSplit = Math.max(split - (isCode ? 10 : wrapLimit-(wrapLimit>>2)), lastSplit - 1); while (split > minSplit && tokens[split] < PLACEHOLDER_START) { split --; } if (isCode) { while (split > minSplit && tokens[split] < PLACEHOLDER_START) { split --; } while (split > minSplit && tokens[split] == PUNCTUATION) { split --; } } else { while (split > minSplit && tokens[split] < SPACE) { split --; } } if (split > minSplit) { addSplit(++split); continue; } split = lastSplit + wrapLimit; if (tokens[split] == CHAR_EXT) split--; addSplit(split); } return splits; }; this.$getDisplayTokens = function(str, offset) { var arr = []; var tabSize; offset = offset || 0; for (var i = 0; i < str.length; i++) { var c = str.charCodeAt(i); if (c == 9) { tabSize = this.getScreenTabSize(arr.length + offset); arr.push(TAB); for (var n = 1; n < tabSize; n++) { arr.push(TAB_SPACE); } } else if (c == 32) { arr.push(SPACE); } else if((c > 39 && c < 48) || (c > 57 && c < 64)) { arr.push(PUNCTUATION); } else if (c >= 0x1100 && isFullWidth(c)) { arr.push(CHAR, CHAR_EXT); } else { arr.push(CHAR); } } return arr; }; this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) { if (maxScreenColumn == 0) return [0, 0]; if (maxScreenColumn == null) maxScreenColumn = Infinity; screenColumn = screenColumn || 0; var c, column; for (column = 0; column < str.length; column++) { c = str.charCodeAt(column); if (c == 9) { screenColumn += this.getScreenTabSize(screenColumn); } else if (c >= 0x1100 && isFullWidth(c)) { screenColumn += 2; } else { screenColumn += 1; } if (screenColumn > maxScreenColumn) { break; } } return [screenColumn, column]; }; this.lineWidgets = null; this.getRowLength = function(row) { if (this.lineWidgets) var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; else h = 0 if (!this.$useWrapMode || !this.$wrapData[row]) { return 1 + h; } else { return this.$wrapData[row].length + 1 + h; } }; this.getRowLineCount = function(row) { if (!this.$useWrapMode || !this.$wrapData[row]) { return 1; } else { return this.$wrapData[row].length + 1; } }; this.getScreenLastRowColumn = function(screenRow) { var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE); return this.documentToScreenColumn(pos.row, pos.column); }; this.getDocumentLastRowColumn = function(docRow, docColumn) { var screenRow = this.documentToScreenRow(docRow, docColumn); return this.getScreenLastRowColumn(screenRow); }; this.getDocumentLastRowColumnPosition = function(docRow, docColumn) { var screenRow = this.documentToScreenRow(docRow, docColumn); return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10); }; this.getRowSplitData = function(row) { if (!this.$useWrapMode) { return undefined; } else { return this.$wrapData[row]; } }; this.getScreenTabSize = function(screenColumn) { return this.$tabSize - screenColumn % this.$tabSize; }; this.screenToDocumentRow = function(screenRow, screenColumn) { return this.screenToDocumentPosition(screenRow, screenColumn).row; }; this.screenToDocumentColumn = function(screenRow, screenColumn) { return this.screenToDocumentPosition(screenRow, screenColumn).column; }; this.screenToDocumentPosition = function(screenRow, screenColumn) { if (screenRow < 0) return {row: 0, column: 0}; var line; var docRow = 0; var docColumn = 0; var column; var row = 0; var rowLength = 0; var rowCache = this.$screenRowCache; var i = this.$getRowCacheIndex(rowCache, screenRow); var l = rowCache.length; if (l && i >= 0) { var row = rowCache[i]; var docRow = this.$docRowCache[i]; var doCache = screenRow > rowCache[l - 1]; } else { var doCache = !l; } var maxRow = this.getLength() - 1; var foldLine = this.getNextFoldLine(docRow); var foldStart = foldLine ? foldLine.start.row : Infinity; while (row <= screenRow) { rowLength = this.getRowLength(docRow); if (row + rowLength > screenRow || docRow >= maxRow) { break; } else { row += rowLength; docRow++; if (docRow > foldStart) { docRow = foldLine.end.row+1; foldLine = this.getNextFoldLine(docRow, foldLine); foldStart = foldLine ? foldLine.start.row : Infinity; } } if (doCache) { this.$docRowCache.push(docRow); this.$screenRowCache.push(row); } } if (foldLine && foldLine.start.row <= docRow) { line = this.getFoldDisplayLine(foldLine); docRow = foldLine.start.row; } else if (row + rowLength <= screenRow || docRow > maxRow) { return { row: maxRow, column: this.getLine(maxRow).length }; } else { line = this.getLine(docRow); foldLine = null; } if (this.$useWrapMode) { var splits = this.$wrapData[docRow]; if (splits) { var splitIndex = Math.floor(screenRow - row); column = splits[splitIndex]; if(splitIndex > 0 && splits.length) { docColumn = splits[splitIndex - 1] || splits[splits.length - 1]; line = line.substring(docColumn); } } } docColumn += this.$getStringScreenWidth(line, screenColumn)[1]; if (this.$useWrapMode && docColumn >= column) docColumn = column - 1; if (foldLine) return foldLine.idxToPosition(docColumn); return {row: docRow, column: docColumn}; }; this.documentToScreenPosition = function(docRow, docColumn) { if (typeof docColumn === "undefined") var pos = this.$clipPositionToDocument(docRow.row, docRow.column); else pos = this.$clipPositionToDocument(docRow, docColumn); docRow = pos.row; docColumn = pos.column; var screenRow = 0; var foldStartRow = null; var fold = null; fold = this.getFoldAt(docRow, docColumn, 1); if (fold) { docRow = fold.start.row; docColumn = fold.start.column; } var rowEnd, row = 0; var rowCache = this.$docRowCache; var i = this.$getRowCacheIndex(rowCache, docRow); var l = rowCache.length; if (l && i >= 0) { var row = rowCache[i]; var screenRow = this.$screenRowCache[i]; var doCache = docRow > rowCache[l - 1]; } else { var doCache = !l; } var foldLine = this.getNextFoldLine(row); var foldStart = foldLine ?foldLine.start.row :Infinity; while (row < docRow) { if (row >= foldStart) { rowEnd = foldLine.end.row + 1; if (rowEnd > docRow) break; foldLine = this.getNextFoldLine(rowEnd, foldLine); foldStart = foldLine ?foldLine.start.row :Infinity; } else { rowEnd = row + 1; } screenRow += this.getRowLength(row); row = rowEnd; if (doCache) { this.$docRowCache.push(row); this.$screenRowCache.push(screenRow); } } var textLine = ""; if (foldLine && row >= foldStart) { textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn); foldStartRow = foldLine.start.row; } else { textLine = this.getLine(docRow).substring(0, docColumn); foldStartRow = docRow; } if (this.$useWrapMode) { var wrapRow = this.$wrapData[foldStartRow]; if (wrapRow) { var screenRowOffset = 0; while (textLine.length >= wrapRow[screenRowOffset]) { screenRow ++; screenRowOffset++; } textLine = textLine.substring( wrapRow[screenRowOffset - 1] || 0, textLine.length ); } } return { row: screenRow, column: this.$getStringScreenWidth(textLine)[0] }; }; this.documentToScreenColumn = function(row, docColumn) { return this.documentToScreenPosition(row, docColumn).column; }; this.documentToScreenRow = function(docRow, docColumn) { return this.documentToScreenPosition(docRow, docColumn).row; }; this.getScreenLength = function() { var screenRows = 0; var fold = null; if (!this.$useWrapMode) { screenRows = this.getLength(); var foldData = this.$foldData; for (var i = 0; i < foldData.length; i++) { fold = foldData[i]; screenRows -= fold.end.row - fold.start.row; } } else { var lastRow = this.$wrapData.length; var row = 0, i = 0; var fold = this.$foldData[i++]; var foldStart = fold ? fold.start.row :Infinity; while (row < lastRow) { var splits = this.$wrapData[row]; screenRows += splits ? splits.length + 1 : 1; row ++; if (row > foldStart) { row = fold.end.row+1; fold = this.$foldData[i++]; foldStart = fold ?fold.start.row :Infinity; } } } if (this.lineWidgets) screenRows += this.$getWidgetScreenLength(); return screenRows; }; this.$setFontMetrics = function(fm) { }; this.destroy = function() { if (this.bgTokenizer) { this.bgTokenizer.setDocument(null); this.bgTokenizer = null; } this.$stopWorker(); }; function isFullWidth(c) { if (c < 0x1100) return false; return c >= 0x1100 && c <= 0x115F || c >= 0x11A3 && c <= 0x11A7 || c >= 0x11FA && c <= 0x11FF || c >= 0x2329 && c <= 0x232A || c >= 0x2E80 && c <= 0x2E99 || c >= 0x2E9B && c <= 0x2EF3 || c >= 0x2F00 && c <= 0x2FD5 || c >= 0x2FF0 && c <= 0x2FFB || c >= 0x3000 && c <= 0x303E || c >= 0x3041 && c <= 0x3096 || c >= 0x3099 && c <= 0x30FF || c >= 0x3105 && c <= 0x312D || c >= 0x3131 && c <= 0x318E || c >= 0x3190 && c <= 0x31BA || c >= 0x31C0 && c <= 0x31E3 || c >= 0x31F0 && c <= 0x321E || c >= 0x3220 && c <= 0x3247 || c >= 0x3250 && c <= 0x32FE || c >= 0x3300 && c <= 0x4DBF || c >= 0x4E00 && c <= 0xA48C || c >= 0xA490 && c <= 0xA4C6 || c >= 0xA960 && c <= 0xA97C || c >= 0xAC00 && c <= 0xD7A3 || c >= 0xD7B0 && c <= 0xD7C6 || c >= 0xD7CB && c <= 0xD7FB || c >= 0xF900 && c <= 0xFAFF || c >= 0xFE10 && c <= 0xFE19 || c >= 0xFE30 && c <= 0xFE52 || c >= 0xFE54 && c <= 0xFE66 || c >= 0xFE68 && c <= 0xFE6B || c >= 0xFF01 && c <= 0xFF60 || c >= 0xFFE0 && c <= 0xFFE6; }; }).call(EditSession.prototype); require("./edit_session/folding").Folding.call(EditSession.prototype); require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype); config.defineOptions(EditSession.prototype, "session", { wrap: { set: function(value) { if (!value || value == "off") value = false; else if (value == "free") value = true; else if (value == "printMargin") value = -1; else if (typeof value == "string") value = parseInt(value, 10) || false; if (this.$wrap == value) return; if (!value) { this.setUseWrapMode(false); } else { var col = typeof value == "number" ? value : null; this.setWrapLimitRange(col, col); this.setUseWrapMode(true); } this.$wrap = value; }, get: function() { if (this.getUseWrapMode()) { if (this.$wrap == -1) return "printMargin"; if (!this.getWrapLimitRange().min) return "free"; return this.$wrap; } return "off"; }, handlesSet: true }, wrapMethod: { set: function(val) { val = val == "auto" ? this.$mode.type != "text" : val != "text"; if (val != this.$wrapAsCode) { this.$wrapAsCode = val; if (this.$useWrapMode) { this.$modified = true; this.$resetRowCache(0); this.$updateWrapData(0, this.getLength() - 1); } } }, initialValue: "auto" }, firstLineNumber: { set: function() {this._signal("changeBreakpoint");}, initialValue: 1 }, useWorker: { set: function(useWorker) { this.$useWorker = useWorker; this.$stopWorker(); if (useWorker) this.$startWorker(); }, initialValue: true }, useSoftTabs: {initialValue: true}, tabSize: { set: function(tabSize) { if (isNaN(tabSize) || this.$tabSize === tabSize) return; this.$modified = true; this.$rowLengthCache = []; this.$tabSize = tabSize; this._signal("changeTabSize"); }, initialValue: 4, handlesSet: true }, overwrite: { set: function(val) {this._signal("changeOverwrite");}, initialValue: false }, newLineMode: { set: function(val) {this.doc.setNewLineMode(val)}, get: function() {return this.doc.getNewLineMode()}, handlesSet: true }, mode: { set: function(val) { this.setMode(val) }, get: function() { return this.$modeId } } }); exports.EditSession = EditSession; }); ace.define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(require, exports, module) { "use strict"; var lang = require("./lib/lang"); var oop = require("./lib/oop"); var Range = require("./range").Range; var Search = function() { this.$options = {}; }; (function() { this.set = function(options) { oop.mixin(this.$options, options); return this; }; this.getOptions = function() { return lang.copyObject(this.$options); }; this.setOptions = function(options) { this.$options = options; }; this.find = function(session) { var iterator = this.$matchIterator(session, this.$options); if (!iterator) return false; var firstRange = null; iterator.forEach(function(range, row, offset) { if (!range.start) { var column = range.offset + (offset || 0); firstRange = new Range(row, column, row, column+range.length); } else firstRange = range; return true; }); return firstRange; }; this.findAll = function(session) { var options = this.$options; if (!options.needle) return []; this.$assembleRegExp(options); var range = options.range; var lines = range ? session.getLines(range.start.row, range.end.row) : session.doc.getAllLines(); var ranges = []; var re = options.re; if (options.$isMultiLine) { var len = re.length; var maxRow = lines.length - len; var prevRange; outer: for (var row = re.offset || 0; row <= maxRow; row++) { for (var j = 0; j < len; j++) if (lines[row + j].search(re[j]) == -1) continue outer; var startLine = lines[row]; var line = lines[row + len - 1]; var startIndex = startLine.length - startLine.match(re[0])[0].length; var endIndex = line.match(re[len - 1])[0].length; if (prevRange && prevRange.end.row === row && prevRange.end.column > startIndex ) { continue; } ranges.push(prevRange = new Range( row, startIndex, row + len - 1, endIndex )); if (len > 2) row = row + len - 2; } } else { for (var i = 0; i < lines.length; i++) { var matches = lang.getMatchOffsets(lines[i], re); for (var j = 0; j < matches.length; j++) { var match = matches[j]; ranges.push(new Range(i, match.offset, i, match.offset + match.length)); } } } if (range) { var startColumn = range.start.column; var endColumn = range.start.column; var i = 0, j = ranges.length - 1; while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row) i++; while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row) j--; ranges = ranges.slice(i, j + 1); for (i = 0, j = ranges.length; i < j; i++) { ranges[i].start.row += range.start.row; ranges[i].end.row += range.start.row; } } return ranges; }; this.replace = function(input, replacement) { var options = this.$options; var re = this.$assembleRegExp(options); if (options.$isMultiLine) return replacement; if (!re) return; var match = re.exec(input); if (!match || match[0].length != input.length) return null; replacement = input.replace(re, replacement); if (options.preserveCase) { replacement = replacement.split(""); for (var i = Math.min(input.length, input.length); i--; ) { var ch = input[i]; if (ch && ch.toLowerCase() != ch) replacement[i] = replacement[i].toUpperCase(); else replacement[i] = replacement[i].toLowerCase(); } replacement = replacement.join(""); } return replacement; }; this.$matchIterator = function(session, options) { var re = this.$assembleRegExp(options); if (!re) return false; var self = this, callback, backwards = options.backwards; if (options.$isMultiLine) { var len = re.length; var matchIterator = function(line, row, offset) { var startIndex = line.search(re[0]); if (startIndex == -1) return; for (var i = 1; i < len; i++) { line = session.getLine(row + i); if (line.search(re[i]) == -1) return; } var endIndex = line.match(re[len - 1])[0].length; var range = new Range(row, startIndex, row + len - 1, endIndex); if (re.offset == 1) { range.start.row--; range.start.column = Number.MAX_VALUE; } else if (offset) range.start.column += offset; if (callback(range)) return true; }; } else if (backwards) { var matchIterator = function(line, row, startIndex) { var matches = lang.getMatchOffsets(line, re); for (var i = matches.length-1; i >= 0; i--) if (callback(matches[i], row, startIndex)) return true; }; } else { var matchIterator = function(line, row, startIndex) { var matches = lang.getMatchOffsets(line, re); for (var i = 0; i < matches.length; i++) if (callback(matches[i], row, startIndex)) return true; }; } return { forEach: function(_callback) { callback = _callback; self.$lineIterator(session, options).forEach(matchIterator); } }; }; this.$assembleRegExp = function(options, $disableFakeMultiline) { if (options.needle instanceof RegExp) return options.re = options.needle; var needle = options.needle; if (!options.needle) return options.re = false; if (!options.regExp) needle = lang.escapeRegExp(needle); if (options.wholeWord) needle = "\\b" + needle + "\\b"; var modifier = options.caseSensitive ? "gm" : "gmi"; options.$isMultiLine = !$disableFakeMultiline && /[\n\r]/.test(needle); if (options.$isMultiLine) return options.re = this.$assembleMultilineRegExp(needle, modifier); try { var re = new RegExp(needle, modifier); } catch(e) { re = false; } return options.re = re; }; this.$assembleMultilineRegExp = function(needle, modifier) { var parts = needle.replace(/\r\n|\r|\n/g, "$\n^").split("\n"); var re = []; for (var i = 0; i < parts.length; i++) try { re.push(new RegExp(parts[i], modifier)); } catch(e) { return false; } if (parts[0] == "") { re.shift(); re.offset = 1; } else { re.offset = 0; } return re; }; this.$lineIterator = function(session, options) { var backwards = options.backwards == true; var skipCurrent = options.skipCurrent != false; var range = options.range; var start = options.start; if (!start) start = range ? range[backwards ? "end" : "start"] : session.selection.getRange(); if (start.start) start = start[skipCurrent != backwards ? "end" : "start"]; var firstRow = range ? range.start.row : 0; var lastRow = range ? range.end.row : session.getLength() - 1; var forEach = backwards ? function(callback) { var row = start.row; var line = session.getLine(row).substring(0, start.column); if (callback(line, row)) return; for (row--; row >= firstRow; row--) if (callback(session.getLine(row), row)) return; if (options.wrap == false) return; for (row = lastRow, firstRow = start.row; row >= firstRow; row--) if (callback(session.getLine(row), row)) return; } : function(callback) { var row = start.row; var line = session.getLine(row).substr(start.column); if (callback(line, row, start.column)) return; for (row = row+1; row <= lastRow; row++) if (callback(session.getLine(row), row)) return; if (options.wrap == false) return; for (row = firstRow, lastRow = start.row; row <= lastRow; row++) if (callback(session.getLine(row), row)) return; }; return {forEach: forEach}; }; }).call(Search.prototype); exports.Search = Search; }); ace.define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) { "use strict"; var keyUtil = require("../lib/keys"); var useragent = require("../lib/useragent"); var KEY_MODS = keyUtil.KEY_MODS; function HashHandler(config, platform) { this.platform = platform || (useragent.isMac ? "mac" : "win"); this.commands = {}; this.commandKeyBinding = {}; this.addCommands(config); this.$singleCommand = true; } function MultiHashHandler(config, platform) { HashHandler.call(this, config, platform); this.$singleCommand = false; } MultiHashHandler.prototype = HashHandler.prototype; (function() { this.addCommand = function(command) { if (this.commands[command.name]) this.removeCommand(command); this.commands[command.name] = command; if (command.bindKey) this._buildKeyHash(command); }; this.removeCommand = function(command, keepCommand) { var name = command && (typeof command === 'string' ? command : command.name); command = this.commands[name]; if (!keepCommand) delete this.commands[name]; var ckb = this.commandKeyBinding; for (var keyId in ckb) { var cmdGroup = ckb[keyId]; if (cmdGroup == command) { delete ckb[keyId]; } else if (Array.isArray(cmdGroup)) { var i = cmdGroup.indexOf(command); if (i != -1) { cmdGroup.splice(i, 1); if (cmdGroup.length == 1) ckb[keyId] = cmdGroup[0]; } } } }; this.bindKey = function(key, command, asDefault) { if (typeof key == "object") key = key[this.platform]; if (!key) return; if (typeof command == "function") return this.addCommand({exec: command, bindKey: key, name: command.name || key}); key.split("|").forEach(function(keyPart) { var chain = ""; if (keyPart.indexOf(" ") != -1) { var parts = keyPart.split(/\s+/); keyPart = parts.pop(); parts.forEach(function(keyPart) { var binding = this.parseKeys(keyPart); var id = KEY_MODS[binding.hashId] + binding.key; chain += (chain ? " " : "") + id; this._addCommandToBinding(chain, "chainKeys"); }, this); chain += " "; } var binding = this.parseKeys(keyPart); var id = KEY_MODS[binding.hashId] + binding.key; this._addCommandToBinding(chain + id, command, asDefault); }, this); }; this._addCommandToBinding = function(keyId, command, asDefault) { var ckb = this.commandKeyBinding, i; if (!command) { delete ckb[keyId]; } else if (!ckb[keyId] || this.$singleCommand) { ckb[keyId] = command; } else { if (!Array.isArray(ckb[keyId])) { ckb[keyId] = [ckb[keyId]]; } else if ((i = ckb[keyId].indexOf(command)) != -1) { ckb[keyId].splice(i, 1); } if (asDefault || command.isDefault) ckb[keyId].unshift(command); else ckb[keyId].push(command); } }; this.addCommands = function(commands) { commands && Object.keys(commands).forEach(function(name) { var command = commands[name]; if (!command) return; if (typeof command === "string") return this.bindKey(command, name); if (typeof command === "function") command = { exec: command }; if (typeof command !== "object") return; if (!command.name) command.name = name; this.addCommand(command); }, this); }; this.removeCommands = function(commands) { Object.keys(commands).forEach(function(name) { this.removeCommand(commands[name]); }, this); }; this.bindKeys = function(keyList) { Object.keys(keyList).forEach(function(key) { this.bindKey(key, keyList[key]); }, this); }; this._buildKeyHash = function(command) { this.bindKey(command.bindKey, command); }; this.parseKeys = function(keys) { var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x}); var key = parts.pop(); var keyCode = keyUtil[key]; if (keyUtil.FUNCTION_KEYS[keyCode]) key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase(); else if (!parts.length) return {key: key, hashId: -1}; else if (parts.length == 1 && parts[0] == "shift") return {key: key.toUpperCase(), hashId: -1}; var hashId = 0; for (var i = parts.length; i--;) { var modifier = keyUtil.KEY_MODS[parts[i]]; if (modifier == null) { if (typeof console != "undefined") console.error("invalid modifier " + parts[i] + " in " + keys); return false; } hashId |= modifier; } return {key: key, hashId: hashId}; }; this.findKeyCommand = function findKeyCommand(hashId, keyString) { var key = KEY_MODS[hashId] + keyString; return this.commandKeyBinding[key]; }; this.handleKeyboard = function(data, hashId, keyString, keyCode) { var key = KEY_MODS[hashId] + keyString; var command = this.commandKeyBinding[key]; if (data.$keyChain) { data.$keyChain += " " + key; command = this.commandKeyBinding[data.$keyChain] || command; } if (command) { if (command == "chainKeys" || command[command.length - 1] == "chainKeys") { data.$keyChain = data.$keyChain || key; return {command: "null"}; } } if (data.$keyChain && keyCode > 0) data.$keyChain = ""; return {command: command}; }; }).call(HashHandler.prototype); exports.HashHandler = HashHandler; exports.MultiHashHandler = MultiHashHandler; }); ace.define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var MultiHashHandler = require("../keyboard/hash_handler").MultiHashHandler; var EventEmitter = require("../lib/event_emitter").EventEmitter; var CommandManager = function(platform, commands) { MultiHashHandler.call(this, commands, platform); this.byName = this.commands; this.setDefaultHandler("exec", function(e) { return e.command.exec(e.editor, e.args || {}); }); }; oop.inherits(CommandManager, MultiHashHandler); (function() { oop.implement(this, EventEmitter); this.exec = function(command, editor, args) { if (Array.isArray(command)) { for (var i = command.length; i--; ) { if (this.exec(command[i], editor, args)) return true; } return false; } if (typeof command === "string") command = this.commands[command]; if (!command) return false; if (editor && editor.$readOnly && !command.readOnly) return false; var e = {editor: editor, command: command, args: args}; e.returnValue = this._emit("exec", e); this._signal("afterExec", e); return e.returnValue === false ? false : true; }; this.toggleRecording = function(editor) { if (this.$inReplay) return; editor && editor._emit("changeStatus"); if (this.recording) { this.macro.pop(); this.removeEventListener("exec", this.$addCommandToMacro); if (!this.macro.length) this.macro = this.oldMacro; return this.recording = false; } if (!this.$addCommandToMacro) { this.$addCommandToMacro = function(e) { this.macro.push([e.command, e.args]); }.bind(this); } this.oldMacro = this.macro; this.macro = []; this.on("exec", this.$addCommandToMacro); return this.recording = true; }; this.replay = function(editor) { if (this.$inReplay || !this.macro) return; if (this.recording) return this.toggleRecording(editor); try { this.$inReplay = true; this.macro.forEach(function(x) { if (typeof x == "string") this.exec(x, editor); else this.exec(x[0], editor, x[1]); }, this); } finally { this.$inReplay = false; } }; this.trimMacro = function(m) { return m.map(function(x){ if (typeof x[0] != "string") x[0] = x[0].name; if (!x[1]) x = x[0]; return x; }); }; }).call(CommandManager.prototype); exports.CommandManager = CommandManager; }); ace.define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"], function(require, exports, module) { "use strict"; var lang = require("../lib/lang"); var config = require("../config"); var Range = require("../range").Range; function bindKey(win, mac) { return {win: win, mac: mac}; } exports.commands = [{ name: "showSettingsMenu", bindKey: bindKey("Ctrl-,", "Command-,"), exec: function(editor) { config.loadModule("ace/ext/settings_menu", function(module) { module.init(editor); editor.showSettingsMenu(); }); }, readOnly: true }, { name: "goToNextError", bindKey: bindKey("Alt-E", "Ctrl-E"), exec: function(editor) { config.loadModule("ace/ext/error_marker", function(module) { module.showErrorMarker(editor, 1); }); }, scrollIntoView: "animate", readOnly: true }, { name: "goToPreviousError", bindKey: bindKey("Alt-Shift-E", "Ctrl-Shift-E"), exec: function(editor) { config.loadModule("ace/ext/error_marker", function(module) { module.showErrorMarker(editor, -1); }); }, scrollIntoView: "animate", readOnly: true }, { name: "selectall", bindKey: bindKey("Ctrl-A", "Command-A"), exec: function(editor) { editor.selectAll(); }, readOnly: true }, { name: "centerselection", bindKey: bindKey(null, "Ctrl-L"), exec: function(editor) { editor.centerSelection(); }, readOnly: true }, { name: "gotoline", bindKey: bindKey("Ctrl-L", "Command-L"), exec: function(editor) { var line = parseInt(prompt("Enter line number:"), 10); if (!isNaN(line)) { editor.gotoLine(line); } }, readOnly: true }, { name: "fold", bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"), exec: function(editor) { editor.session.toggleFold(false); }, scrollIntoView: "center", readOnly: true }, { name: "unfold", bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"), exec: function(editor) { editor.session.toggleFold(true); }, scrollIntoView: "center", readOnly: true }, { name: "toggleFoldWidget", bindKey: bindKey("F2", "F2"), exec: function(editor) { editor.session.toggleFoldWidget(); }, scrollIntoView: "center", readOnly: true }, { name: "toggleParentFoldWidget", bindKey: bindKey("Alt-F2", "Alt-F2"), exec: function(editor) { editor.session.toggleFoldWidget(true); }, scrollIntoView: "center", readOnly: true }, { name: "foldall", bindKey: bindKey("Ctrl-Alt-0", "Ctrl-Command-Option-0"), exec: function(editor) { editor.session.foldAll(); }, scrollIntoView: "center", readOnly: true }, { name: "foldOther", bindKey: bindKey("Alt-0", "Command-Option-0"), exec: function(editor) { editor.session.foldAll(); editor.session.unfold(editor.selection.getAllRanges()); }, scrollIntoView: "center", readOnly: true }, { name: "unfoldall", bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"), exec: function(editor) { editor.session.unfold(); }, scrollIntoView: "center", readOnly: true }, { name: "findnext", bindKey: bindKey("Ctrl-K", "Command-G"), exec: function(editor) { editor.findNext(); }, multiSelectAction: "forEach", scrollIntoView: "center", readOnly: true }, { name: "findprevious", bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"), exec: function(editor) { editor.findPrevious(); }, multiSelectAction: "forEach", scrollIntoView: "center", readOnly: true }, { name: "selectOrFindNext", bindKey: bindKey("Alt-K", "Ctrl-G"), exec: function(editor) { if (editor.selection.isEmpty()) editor.selection.selectWord(); else editor.findNext(); }, readOnly: true }, { name: "selectOrFindPrevious", bindKey: bindKey("Alt-Shift-K", "Ctrl-Shift-G"), exec: function(editor) { if (editor.selection.isEmpty()) editor.selection.selectWord(); else editor.findPrevious(); }, readOnly: true }, { name: "find", bindKey: bindKey("Ctrl-F", "Command-F"), exec: function(editor) { config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor)}); }, readOnly: true }, { name: "overwrite", bindKey: "Insert", exec: function(editor) { editor.toggleOverwrite(); }, readOnly: true }, { name: "selecttostart", bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"), exec: function(editor) { editor.getSelection().selectFileStart(); }, multiSelectAction: "forEach", readOnly: true, scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "gotostart", bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"), exec: function(editor) { editor.navigateFileStart(); }, multiSelectAction: "forEach", readOnly: true, scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "selectup", bindKey: bindKey("Shift-Up", "Shift-Up"), exec: function(editor) { editor.getSelection().selectUp(); }, multiSelectAction: "forEach", readOnly: true }, { name: "golineup", bindKey: bindKey("Up", "Up|Ctrl-P"), exec: function(editor, args) { editor.navigateUp(args.times); }, multiSelectAction: "forEach", readOnly: true }, { name: "selecttoend", bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-Down"), exec: function(editor) { editor.getSelection().selectFileEnd(); }, multiSelectAction: "forEach", readOnly: true, scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "gotoend", bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"), exec: function(editor) { editor.navigateFileEnd(); }, multiSelectAction: "forEach", readOnly: true, scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "selectdown", bindKey: bindKey("Shift-Down", "Shift-Down"), exec: function(editor) { editor.getSelection().selectDown(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "golinedown", bindKey: bindKey("Down", "Down|Ctrl-N"), exec: function(editor, args) { editor.navigateDown(args.times); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "selectwordleft", bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"), exec: function(editor) { editor.getSelection().selectWordLeft(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "gotowordleft", bindKey: bindKey("Ctrl-Left", "Option-Left"), exec: function(editor) { editor.navigateWordLeft(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "selecttolinestart", bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"), exec: function(editor) { editor.getSelection().selectLineStart(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "gotolinestart", bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"), exec: function(editor) { editor.navigateLineStart(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "selectleft", bindKey: bindKey("Shift-Left", "Shift-Left"), exec: function(editor) { editor.getSelection().selectLeft(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "gotoleft", bindKey: bindKey("Left", "Left|Ctrl-B"), exec: function(editor, args) { editor.navigateLeft(args.times); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "selectwordright", bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"), exec: function(editor) { editor.getSelection().selectWordRight(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "gotowordright", bindKey: bindKey("Ctrl-Right", "Option-Right"), exec: function(editor) { editor.navigateWordRight(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "selecttolineend", bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"), exec: function(editor) { editor.getSelection().selectLineEnd(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "gotolineend", bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"), exec: function(editor) { editor.navigateLineEnd(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "selectright", bindKey: bindKey("Shift-Right", "Shift-Right"), exec: function(editor) { editor.getSelection().selectRight(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "gotoright", bindKey: bindKey("Right", "Right|Ctrl-F"), exec: function(editor, args) { editor.navigateRight(args.times); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "selectpagedown", bindKey: "Shift-PageDown", exec: function(editor) { editor.selectPageDown(); }, readOnly: true }, { name: "pagedown", bindKey: bindKey(null, "Option-PageDown"), exec: function(editor) { editor.scrollPageDown(); }, readOnly: true }, { name: "gotopagedown", bindKey: bindKey("PageDown", "PageDown|Ctrl-V"), exec: function(editor) { editor.gotoPageDown(); }, readOnly: true }, { name: "selectpageup", bindKey: "Shift-PageUp", exec: function(editor) { editor.selectPageUp(); }, readOnly: true }, { name: "pageup", bindKey: bindKey(null, "Option-PageUp"), exec: function(editor) { editor.scrollPageUp(); }, readOnly: true }, { name: "gotopageup", bindKey: "PageUp", exec: function(editor) { editor.gotoPageUp(); }, readOnly: true }, { name: "scrollup", bindKey: bindKey("Ctrl-Up", null), exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); }, readOnly: true }, { name: "scrolldown", bindKey: bindKey("Ctrl-Down", null), exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); }, readOnly: true }, { name: "selectlinestart", bindKey: "Shift-Home", exec: function(editor) { editor.getSelection().selectLineStart(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "selectlineend", bindKey: "Shift-End", exec: function(editor) { editor.getSelection().selectLineEnd(); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "togglerecording", bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"), exec: function(editor) { editor.commands.toggleRecording(editor); }, readOnly: true }, { name: "replaymacro", bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"), exec: function(editor) { editor.commands.replay(editor); }, readOnly: true }, { name: "jumptomatching", bindKey: bindKey("Ctrl-P", "Ctrl-P"), exec: function(editor) { editor.jumpToMatching(); }, multiSelectAction: "forEach", readOnly: true }, { name: "selecttomatching", bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"), exec: function(editor) { editor.jumpToMatching(true); }, multiSelectAction: "forEach", readOnly: true }, { name: "passKeysToBrowser", bindKey: bindKey("null", "null"), exec: function() {}, passEvent: true, readOnly: true }, { name: "cut", exec: function(editor) { var range = editor.getSelectionRange(); editor._emit("cut", range); if (!editor.selection.isEmpty()) { editor.session.remove(range); editor.clearSelection(); } }, scrollIntoView: "cursor", multiSelectAction: "forEach" }, { name: "removeline", bindKey: bindKey("Ctrl-D", "Command-D"), exec: function(editor) { editor.removeLines(); }, scrollIntoView: "cursor", multiSelectAction: "forEachLine" }, { name: "duplicateSelection", bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"), exec: function(editor) { editor.duplicateSelection(); }, scrollIntoView: "cursor", multiSelectAction: "forEach" }, { name: "sortlines", bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"), exec: function(editor) { editor.sortLines(); }, scrollIntoView: "selection", multiSelectAction: "forEachLine" }, { name: "togglecomment", bindKey: bindKey("Ctrl-/", "Command-/"), exec: function(editor) { editor.toggleCommentLines(); }, multiSelectAction: "forEachLine", scrollIntoView: "selectionPart" }, { name: "toggleBlockComment", bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"), exec: function(editor) { editor.toggleBlockComment(); }, multiSelectAction: "forEach", scrollIntoView: "selectionPart" }, { name: "modifyNumberUp", bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"), exec: function(editor) { editor.modifyNumber(1); }, multiSelectAction: "forEach" }, { name: "modifyNumberDown", bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"), exec: function(editor) { editor.modifyNumber(-1); }, multiSelectAction: "forEach" }, { name: "replace", bindKey: bindKey("Ctrl-H", "Command-Option-F"), exec: function(editor) { config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true)}); } }, { name: "undo", bindKey: bindKey("Ctrl-Z", "Command-Z"), exec: function(editor) { editor.undo(); } }, { name: "redo", bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"), exec: function(editor) { editor.redo(); } }, { name: "copylinesup", bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"), exec: function(editor) { editor.copyLinesUp(); }, scrollIntoView: "cursor" }, { name: "movelinesup", bindKey: bindKey("Alt-Up", "Option-Up"), exec: function(editor) { editor.moveLinesUp(); }, scrollIntoView: "cursor" }, { name: "copylinesdown", bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"), exec: function(editor) { editor.copyLinesDown(); }, scrollIntoView: "cursor" }, { name: "movelinesdown", bindKey: bindKey("Alt-Down", "Option-Down"), exec: function(editor) { editor.moveLinesDown(); }, scrollIntoView: "cursor" }, { name: "del", bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"), exec: function(editor) { editor.remove("right"); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "backspace", bindKey: bindKey( "Shift-Backspace|Backspace", "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H" ), exec: function(editor) { editor.remove("left"); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "cut_or_delete", bindKey: bindKey("Shift-Delete", null), exec: function(editor) { if (editor.selection.isEmpty()) { editor.remove("left"); } else { return false; } }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "removetolinestart", bindKey: bindKey("Alt-Backspace", "Command-Backspace"), exec: function(editor) { editor.removeToLineStart(); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "removetolineend", bindKey: bindKey("Alt-Delete", "Ctrl-K"), exec: function(editor) { editor.removeToLineEnd(); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "removewordleft", bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"), exec: function(editor) { editor.removeWordLeft(); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "removewordright", bindKey: bindKey("Ctrl-Delete", "Alt-Delete"), exec: function(editor) { editor.removeWordRight(); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "outdent", bindKey: bindKey("Shift-Tab", "Shift-Tab"), exec: function(editor) { editor.blockOutdent(); }, multiSelectAction: "forEach", scrollIntoView: "selectionPart" }, { name: "indent", bindKey: bindKey("Tab", "Tab"), exec: function(editor) { editor.indent(); }, multiSelectAction: "forEach", scrollIntoView: "selectionPart" }, { name: "blockoutdent", bindKey: bindKey("Ctrl-[", "Ctrl-["), exec: function(editor) { editor.blockOutdent(); }, multiSelectAction: "forEachLine", scrollIntoView: "selectionPart" }, { name: "blockindent", bindKey: bindKey("Ctrl-]", "Ctrl-]"), exec: function(editor) { editor.blockIndent(); }, multiSelectAction: "forEachLine", scrollIntoView: "selectionPart" }, { name: "insertstring", exec: function(editor, str) { editor.insert(str); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "inserttext", exec: function(editor, args) { editor.insert(lang.stringRepeat(args.text || "", args.times || 1)); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "splitline", bindKey: bindKey(null, "Ctrl-O"), exec: function(editor) { editor.splitLine(); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "transposeletters", bindKey: bindKey("Ctrl-T", "Ctrl-T"), exec: function(editor) { editor.transposeLetters(); }, multiSelectAction: function(editor) {editor.transposeSelections(1); }, scrollIntoView: "cursor" }, { name: "touppercase", bindKey: bindKey("Ctrl-U", "Ctrl-U"), exec: function(editor) { editor.toUpperCase(); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "tolowercase", bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"), exec: function(editor) { editor.toLowerCase(); }, multiSelectAction: "forEach", scrollIntoView: "cursor" }, { name: "expandtoline", bindKey: bindKey("Ctrl-Shift-L", "Command-Shift-L"), exec: function(editor) { var range = editor.selection.getRange(); range.start.column = range.end.column = 0; range.end.row++; editor.selection.setRange(range, false); }, multiSelectAction: "forEach", scrollIntoView: "cursor", readOnly: true }, { name: "joinlines", bindKey: bindKey(null, null), exec: function(editor) { var isBackwards = editor.selection.isBackwards(); var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor(); var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead(); var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length var selectedText = editor.session.doc.getTextRange(editor.selection.getRange()); var selectedCount = selectedText.replace(/\n\s*/, " ").length; var insertLine = editor.session.doc.getLine(selectionStart.row); for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) { var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i))); if (curLine.length !== 0) { curLine = " " + curLine; } insertLine += curLine; }; if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) { insertLine += editor.session.doc.getNewLineCharacter(); } editor.clearSelection(); editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine); if (selectedCount > 0) { editor.selection.moveCursorTo(selectionStart.row, selectionStart.column); editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount); } else { firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol; editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol); } }, multiSelectAction: "forEach", readOnly: true }, { name: "invertSelection", bindKey: bindKey(null, null), exec: function(editor) { var endRow = editor.session.doc.getLength() - 1; var endCol = editor.session.doc.getLine(endRow).length; var ranges = editor.selection.rangeList.ranges; var newRanges = []; if (ranges.length < 1) { ranges = [editor.selection.getRange()]; } for (var i = 0; i < ranges.length; i++) { if (i == (ranges.length - 1)) { if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) { newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol)); } } if (i === 0) { if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) { newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column)); } } else { newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column)); } } editor.exitMultiSelectMode(); editor.clearSelection(); for(var i = 0; i < newRanges.length; i++) { editor.selection.addRange(newRanges[i], false); } }, readOnly: true, scrollIntoView: "none" }]; }); ace.define("ace/editor",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/keyboard/textinput","ace/mouse/mouse_handler","ace/mouse/fold_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/range","ace/lib/event_emitter","ace/commands/command_manager","ace/commands/default_commands","ace/config","ace/token_iterator"], function(require, exports, module) { "use strict"; require("./lib/fixoldbrowsers"); var oop = require("./lib/oop"); var dom = require("./lib/dom"); var lang = require("./lib/lang"); var useragent = require("./lib/useragent"); var TextInput = require("./keyboard/textinput").TextInput; var MouseHandler = require("./mouse/mouse_handler").MouseHandler; var FoldHandler = require("./mouse/fold_handler").FoldHandler; var KeyBinding = require("./keyboard/keybinding").KeyBinding; var EditSession = require("./edit_session").EditSession; var Search = require("./search").Search; var Range = require("./range").Range; var EventEmitter = require("./lib/event_emitter").EventEmitter; var CommandManager = require("./commands/command_manager").CommandManager; var defaultCommands = require("./commands/default_commands").commands; var config = require("./config"); var TokenIterator = require("./token_iterator").TokenIterator; var Editor = function(renderer, session) { var container = renderer.getContainerElement(); this.container = container; this.renderer = renderer; this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands); this.textInput = new TextInput(renderer.getTextAreaContainer(), this); this.renderer.textarea = this.textInput.getElement(); this.keyBinding = new KeyBinding(this); this.$mouseHandler = new MouseHandler(this); new FoldHandler(this); this.$blockScrolling = 0; this.$search = new Search().set({ wrap: true }); this.$historyTracker = this.$historyTracker.bind(this); this.commands.on("exec", this.$historyTracker); this.$initOperationListeners(); this._$emitInputEvent = lang.delayedCall(function() { this._signal("input", {}); if (this.session && this.session.bgTokenizer) this.session.bgTokenizer.scheduleStart(); }.bind(this)); this.on("change", function(_, _self) { _self._$emitInputEvent.schedule(31); }); this.setSession(session || new EditSession("")); config.resetOptions(this); config._signal("editor", this); }; (function(){ oop.implement(this, EventEmitter); this.$initOperationListeners = function() { function last(a) {return a[a.length - 1]} this.selections = []; this.commands.on("exec", this.startOperation.bind(this), true); this.commands.on("afterExec", this.endOperation.bind(this), true); this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this)); this.on("change", function() { this.curOp || this.startOperation(); this.curOp.docChanged = true; }.bind(this), true); this.on("changeSelection", function() { this.curOp || this.startOperation(); this.curOp.selectionChanged = true; }.bind(this), true); }; this.curOp = null; this.prevOp = {}; this.startOperation = function(commadEvent) { if (this.curOp) { if (!commadEvent || this.curOp.command) return; this.prevOp = this.curOp; } if (!commadEvent) { this.previousCommand = null; commadEvent = {}; } this.$opResetTimer.schedule(); this.curOp = { command: commadEvent.command || {}, args: commadEvent.args, scrollTop: this.renderer.scrollTop }; }; this.endOperation = function(e) { if (this.curOp) { if (e && e.returnValue === false) return this.curOp = null; var command = this.curOp.command; if (command && command.scrollIntoView) { switch (command.scrollIntoView) { case "center": this.renderer.scrollCursorIntoView(null, 0.5); break; case "animate": case "cursor": this.renderer.scrollCursorIntoView(); break; case "selectionPart": var range = this.selection.getRange(); var config = this.renderer.layerConfig; if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) { this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead); } break; default: break; } if (command.scrollIntoView == "animate") this.renderer.animateScrolling(this.curOp.scrollTop); } this.prevOp = this.curOp; this.curOp = null; } }; this.$mergeableCommands = ["backspace", "del", "insertstring"]; this.$historyTracker = function(e) { if (!this.$mergeUndoDeltas) return; var prev = this.prevOp; var mergeableCommands = this.$mergeableCommands; var shouldMerge = prev.command && (e.command.name == prev.command.name); if (e.command.name == "insertstring") { var text = e.args; if (this.mergeNextCommand === undefined) this.mergeNextCommand = true; shouldMerge = shouldMerge && this.mergeNextCommand // previous command allows to coalesce with && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type this.mergeNextCommand = true; } else { shouldMerge = shouldMerge && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable } if ( this.$mergeUndoDeltas != "always" && Date.now() - this.sequenceStartTime > 2000 ) { shouldMerge = false; // the sequence is too long } if (shouldMerge) this.session.mergeUndoDeltas = true; else if (mergeableCommands.indexOf(e.command.name) !== -1) this.sequenceStartTime = Date.now(); }; this.setKeyboardHandler = function(keyboardHandler, cb) { if (keyboardHandler && typeof keyboardHandler === "string") { this.$keybindingId = keyboardHandler; var _self = this; config.loadModule(["keybinding", keyboardHandler], function(module) { if (_self.$keybindingId == keyboardHandler) _self.keyBinding.setKeyboardHandler(module && module.handler); cb && cb(); }); } else { this.$keybindingId = null; this.keyBinding.setKeyboardHandler(keyboardHandler); cb && cb(); } }; this.getKeyboardHandler = function() { return this.keyBinding.getKeyboardHandler(); }; this.setSession = function(session) { if (this.session == session) return; var oldSession = this.session; if (oldSession) { this.session.removeEventListener("change", this.$onDocumentChange); this.session.removeEventListener("changeMode", this.$onChangeMode); this.session.removeEventListener("tokenizerUpdate", this.$onTokenizerUpdate); this.session.removeEventListener("changeTabSize", this.$onChangeTabSize); this.session.removeEventListener("changeWrapLimit", this.$onChangeWrapLimit); this.session.removeEventListener("changeWrapMode", this.$onChangeWrapMode); this.session.removeEventListener("onChangeFold", this.$onChangeFold); this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker); this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker); this.session.removeEventListener("changeBreakpoint", this.$onChangeBreakpoint); this.session.removeEventListener("changeAnnotation", this.$onChangeAnnotation); this.session.removeEventListener("changeOverwrite", this.$onCursorChange); this.session.removeEventListener("changeScrollTop", this.$onScrollTopChange); this.session.removeEventListener("changeScrollLeft", this.$onScrollLeftChange); var selection = this.session.getSelection(); selection.removeEventListener("changeCursor", this.$onCursorChange); selection.removeEventListener("changeSelection", this.$onSelectionChange); } this.session = session; if (session) { this.$onDocumentChange = this.onDocumentChange.bind(this); session.addEventListener("change", this.$onDocumentChange); this.renderer.setSession(session); this.$onChangeMode = this.onChangeMode.bind(this); session.addEventListener("changeMode", this.$onChangeMode); this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this); session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate); this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer); session.addEventListener("changeTabSize", this.$onChangeTabSize); this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this); session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit); this.$onChangeWrapMode = this.onChangeWrapMode.bind(this); session.addEventListener("changeWrapMode", this.$onChangeWrapMode); this.$onChangeFold = this.onChangeFold.bind(this); session.addEventListener("changeFold", this.$onChangeFold); this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this); this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker); this.$onChangeBackMarker = this.onChangeBackMarker.bind(this); this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker); this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this); this.session.addEventListener("changeBreakpoint", this.$onChangeBreakpoint); this.$onChangeAnnotation = this.onChangeAnnotation.bind(this); this.session.addEventListener("changeAnnotation", this.$onChangeAnnotation); this.$onCursorChange = this.onCursorChange.bind(this); this.session.addEventListener("changeOverwrite", this.$onCursorChange); this.$onScrollTopChange = this.onScrollTopChange.bind(this); this.session.addEventListener("changeScrollTop", this.$onScrollTopChange); this.$onScrollLeftChange = this.onScrollLeftChange.bind(this); this.session.addEventListener("changeScrollLeft", this.$onScrollLeftChange); this.selection = session.getSelection(); this.selection.addEventListener("changeCursor", this.$onCursorChange); this.$onSelectionChange = this.onSelectionChange.bind(this); this.selection.addEventListener("changeSelection", this.$onSelectionChange); this.onChangeMode(); this.$blockScrolling += 1; this.onCursorChange(); this.$blockScrolling -= 1; this.onScrollTopChange(); this.onScrollLeftChange(); this.onSelectionChange(); this.onChangeFrontMarker(); this.onChangeBackMarker(); this.onChangeBreakpoint(); this.onChangeAnnotation(); this.session.getUseWrapMode() && this.renderer.adjustWrapLimit(); this.renderer.updateFull(); } else { this.selection = null; this.renderer.setSession(session); } this._signal("changeSession", { session: session, oldSession: oldSession }); oldSession && oldSession._signal("changeEditor", {oldEditor: this}); session && session._signal("changeEditor", {editor: this}); }; this.getSession = function() { return this.session; }; this.setValue = function(val, cursorPos) { this.session.doc.setValue(val); if (!cursorPos) this.selectAll(); else if (cursorPos == 1) this.navigateFileEnd(); else if (cursorPos == -1) this.navigateFileStart(); return val; }; this.getValue = function() { return this.session.getValue(); }; this.getSelection = function() { return this.selection; }; this.resize = function(force) { this.renderer.onResize(force); }; this.setTheme = function(theme, cb) { this.renderer.setTheme(theme, cb); }; this.getTheme = function() { return this.renderer.getTheme(); }; this.setStyle = function(style) { this.renderer.setStyle(style); }; this.unsetStyle = function(style) { this.renderer.unsetStyle(style); }; this.getFontSize = function () { return this.getOption("fontSize") || dom.computedStyle(this.container, "fontSize"); }; this.setFontSize = function(size) { this.setOption("fontSize", size); }; this.$highlightBrackets = function() { if (this.session.$bracketHighlight) { this.session.removeMarker(this.session.$bracketHighlight); this.session.$bracketHighlight = null; } if (this.$highlightPending) { return; } var self = this; this.$highlightPending = true; setTimeout(function() { self.$highlightPending = false; var session = self.session; if (!session || !session.bgTokenizer) return; var pos = session.findMatchingBracket(self.getCursorPosition()); if (pos) { var range = new Range(pos.row, pos.column, pos.row, pos.column + 1); } else if (session.$mode.getMatching) { var range = session.$mode.getMatching(self.session); } if (range) session.$bracketHighlight = session.addMarker(range, "ace_bracket", "text"); }, 50); }; this.$highlightTags = function() { if (this.$highlightTagPending) return; var self = this; this.$highlightTagPending = true; setTimeout(function() { self.$highlightTagPending = false; var session = self.session; if (!session || !session.bgTokenizer) return; var pos = self.getCursorPosition(); var iterator = new TokenIterator(self.session, pos.row, pos.column); var token = iterator.getCurrentToken(); if (!token || token.type.indexOf('tag-name') === -1) { session.removeMarker(session.$tagHighlight); session.$tagHighlight = null; return; } var tag = token.value; var depth = 0; var prevToken = iterator.stepBackward(); if (prevToken.value == '<'){ do { prevToken = token; token = iterator.stepForward(); if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) { if (prevToken.value === '<'){ depth++; } else if (prevToken.value === '= 0); } else { do { token = prevToken; prevToken = iterator.stepBackward(); if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) { if (prevToken.value === '<') { depth++; } else if (prevToken.value === ' 1)) highlight = false; } if (session.$highlightLineMarker && !highlight) { session.removeMarker(session.$highlightLineMarker.id); session.$highlightLineMarker = null; } else if (!session.$highlightLineMarker && highlight) { var range = new Range(highlight.row, highlight.column, highlight.row, Infinity); range.id = session.addMarker(range, "ace_active-line", "screenLine"); session.$highlightLineMarker = range; } else if (highlight) { session.$highlightLineMarker.start.row = highlight.row; session.$highlightLineMarker.end.row = highlight.row; session.$highlightLineMarker.start.column = highlight.column; session._signal("changeBackMarker"); } }; this.onSelectionChange = function(e) { var session = this.session; if (session.$selectionMarker) { session.removeMarker(session.$selectionMarker); } session.$selectionMarker = null; if (!this.selection.isEmpty()) { var range = this.selection.getRange(); var style = this.getSelectionStyle(); session.$selectionMarker = session.addMarker(range, "ace_selection", style); } else { this.$updateHighlightActiveLine(); } var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp(); this.session.highlight(re); this._signal("changeSelection"); }; this.$getSelectionHighLightRegexp = function() { var session = this.session; var selection = this.getSelectionRange(); if (selection.isEmpty() || selection.isMultiLine()) return; var startOuter = selection.start.column - 1; var endOuter = selection.end.column + 1; var line = session.getLine(selection.start.row); var lineCols = line.length; var needle = line.substring(Math.max(startOuter, 0), Math.min(endOuter, lineCols)); if ((startOuter >= 0 && /^[\w\d]/.test(needle)) || (endOuter <= lineCols && /[\w\d]$/.test(needle))) return; needle = line.substring(selection.start.column, selection.end.column); if (!/^[\w\d]+$/.test(needle)) return; var re = this.$search.$assembleRegExp({ wholeWord: true, caseSensitive: true, needle: needle }); return re; }; this.onChangeFrontMarker = function() { this.renderer.updateFrontMarkers(); }; this.onChangeBackMarker = function() { this.renderer.updateBackMarkers(); }; this.onChangeBreakpoint = function() { this.renderer.updateBreakpoints(); }; this.onChangeAnnotation = function() { this.renderer.setAnnotations(this.session.getAnnotations()); }; this.onChangeMode = function(e) { this.renderer.updateText(); this._emit("changeMode", e); }; this.onChangeWrapLimit = function() { this.renderer.updateFull(); }; this.onChangeWrapMode = function() { this.renderer.onResize(true); }; this.onChangeFold = function() { this.$updateHighlightActiveLine(); this.renderer.updateFull(); }; this.getSelectedText = function() { return this.session.getTextRange(this.getSelectionRange()); }; this.getCopyText = function() { var text = this.getSelectedText(); this._signal("copy", text); return text; }; this.onCopy = function() { this.commands.exec("copy", this); }; this.onCut = function() { this.commands.exec("cut", this); }; this.onPaste = function(text) { if (this.$readOnly) return; var e = {text: text}; this._signal("paste", e); this.insert(e.text, true); }; this.execCommand = function(command, args) { return this.commands.exec(command, this, args); }; this.insert = function(text, pasted) { var session = this.session; var mode = session.getMode(); var cursor = this.getCursorPosition(); if (this.getBehavioursEnabled() && !pasted) { var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text); if (transform) { if (text !== transform.text) { this.session.mergeUndoDeltas = false; this.$mergeNextCommand = false; } text = transform.text; } } if (text == "\t") text = this.session.getTabString(); if (!this.selection.isEmpty()) { var range = this.getSelectionRange(); cursor = this.session.remove(range); this.clearSelection(); } else if (this.session.getOverwrite()) { var range = new Range.fromPoints(cursor, cursor); range.end.column += text.length; this.session.remove(range); } if (text == "\n" || text == "\r\n") { var line = session.getLine(cursor.row); if (cursor.column > line.search(/\S|$/)) { var d = line.substr(cursor.column).search(/\S|$/); session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d); } } this.clearSelection(); var start = cursor.column; var lineState = session.getState(cursor.row); var line = session.getLine(cursor.row); var shouldOutdent = mode.checkOutdent(lineState, line, text); 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])); } } if (session.getDocument().isNewLine(text)) { var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString()); session.insert({row: cursor.row+1, column: 0}, lineIndent); } if (shouldOutdent) mode.autoOutdent(lineState, session, cursor.row); }; this.onTextInput = function(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.setOption("scrollSpeed", speed); }; this.getScrollSpeed = function() { return this.getOption("scrollSpeed"); }; this.setDragDelay = function(dragDelay) { this.setOption("dragDelay", dragDelay); }; this.getDragDelay = function() { return this.getOption("dragDelay"); }; this.setSelectionStyle = function(val) { this.setOption("selectionStyle", val); }; this.getSelectionStyle = function() { return this.getOption("selectionStyle"); }; this.setHighlightActiveLine = function(shouldHighlight) { this.setOption("highlightActiveLine", shouldHighlight); }; this.getHighlightActiveLine = function() { return this.getOption("highlightActiveLine"); }; this.setHighlightGutterLine = function(shouldHighlight) { this.setOption("highlightGutterLine", shouldHighlight); }; this.getHighlightGutterLine = function() { return this.getOption("highlightGutterLine"); }; this.setHighlightSelectedWord = function(shouldHighlight) { this.setOption("highlightSelectedWord", shouldHighlight); }; this.getHighlightSelectedWord = function() { return this.$highlightSelectedWord; }; this.setAnimatedScroll = function(shouldAnimate){ this.renderer.setAnimatedScroll(shouldAnimate); }; this.getAnimatedScroll = function(){ return this.renderer.getAnimatedScroll(); }; this.setShowInvisibles = function(showInvisibles) { this.renderer.setShowInvisibles(showInvisibles); }; this.getShowInvisibles = function() { return this.renderer.getShowInvisibles(); }; this.setDisplayIndentGuides = function(display) { this.renderer.setDisplayIndentGuides(display); }; this.getDisplayIndentGuides = function() { return this.renderer.getDisplayIndentGuides(); }; this.setShowPrintMargin = function(showPrintMargin) { this.renderer.setShowPrintMargin(showPrintMargin); }; this.getShowPrintMargin = function() { return this.renderer.getShowPrintMargin(); }; this.setPrintMarginColumn = function(showPrintMargin) { this.renderer.setPrintMarginColumn(showPrintMargin); }; this.getPrintMarginColumn = function() { return this.renderer.getPrintMarginColumn(); }; this.setReadOnly = function(readOnly) { this.setOption("readOnly", readOnly); }; this.getReadOnly = function() { return this.getOption("readOnly"); }; this.setBehavioursEnabled = function (enabled) { this.setOption("behavioursEnabled", enabled); }; this.getBehavioursEnabled = function () { return this.getOption("behavioursEnabled"); }; this.setWrapBehavioursEnabled = function (enabled) { this.setOption("wrapBehavioursEnabled", enabled); }; this.getWrapBehavioursEnabled = function () { return this.getOption("wrapBehavioursEnabled"); }; this.setShowFoldWidgets = function(show) { this.setOption("showFoldWidgets", show); }; this.getShowFoldWidgets = function() { return this.getOption("showFoldWidgets"); }; this.setFadeFoldWidgets = function(fade) { this.setOption("fadeFoldWidgets", fade); }; this.getFadeFoldWidgets = function() { return this.getOption("fadeFoldWidgets"); }; this.remove = function(dir) { if (this.selection.isEmpty()){ if (dir == "left") this.selection.selectLeft(); else this.selection.selectRight(); } var range = this.getSelectionRange(); if (this.getBehavioursEnabled()) { var session = this.session; var state = session.getState(range.start.row); var new_range = session.getMode().transformAction(state, 'deletion', this, session, range); if (range.end.column === 0) { var text = session.getTextRange(range); if (text[text.length - 1] == "\n") { var line = session.getLine(range.end.row); if (/^\s+$/.test(line)) { range.end.column = line.length; } } } if (new_range) range = new_range; } this.session.remove(range); this.clearSelection(); }; this.removeWordRight = function() { if (this.selection.isEmpty()) this.selection.selectWordRight(); this.session.remove(this.getSelectionRange()); this.clearSelection(); }; this.removeWordLeft = function() { if (this.selection.isEmpty()) this.selection.selectWordLeft(); this.session.remove(this.getSelectionRange()); this.clearSelection(); }; this.removeToLineStart = function() { if (this.selection.isEmpty()) this.selection.selectLineStart(); this.session.remove(this.getSelectionRange()); this.clearSelection(); }; this.removeToLineEnd = function() { if (this.selection.isEmpty()) this.selection.selectLineEnd(); var range = this.getSelectionRange(); if (range.start.column == range.end.column && range.start.row == range.end.row) { range.end.column = 0; range.end.row++; } this.session.remove(range); this.clearSelection(); }; this.splitLine = function() { 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.selection.isEmpty()) { return; } var cursor = this.getCursorPosition(); var column = cursor.column; if (column === 0) return; var line = this.session.getLine(cursor.row); var swap, range; if (column < line.length) { swap = line.charAt(column) + line.charAt(column-1); range = new Range(cursor.row, column-1, cursor.row, column+1); } else { swap = line.charAt(column-1) + line.charAt(column-2); range = new Range(cursor.row, column-2, cursor.row, column); } this.session.replace(range, swap); }; this.toLowerCase = function() { var originalRange = this.getSelectionRange(); if (this.selection.isEmpty()) { this.selection.selectWord(); } var range = this.getSelectionRange(); var text = this.session.getTextRange(range); this.session.replace(range, text.toLowerCase()); this.selection.setSelectionRange(originalRange); }; this.toUpperCase = function() { var originalRange = this.getSelectionRange(); if (this.selection.isEmpty()) { this.selection.selectWord(); } var range = this.getSelectionRange(); var text = this.session.getTextRange(range); this.session.replace(range, text.toUpperCase()); this.selection.setSelectionRange(originalRange); }; this.indent = function() { var session = this.session; var range = this.getSelectionRange(); if (range.start.row < range.end.row) { var rows = this.$getSelectedRows(); session.indentRows(rows.first, rows.last, "\t"); return; } else if (range.start.column < range.end.column) { var text = session.getTextRange(range); if (!/^\s+$/.test(text)) { var rows = this.$getSelectedRows(); session.indentRows(rows.first, rows.last, "\t"); return; } } var line = session.getLine(range.start.row); var position = range.start; var size = session.getTabSize(); var column = session.documentToScreenColumn(position.row, position.column); if (this.session.getUseSoftTabs()) { var count = (size - column % size); var indentString = lang.stringRepeat(" ", count); } else { var count = column % size; while (line[range.start.column] == " " && count) { range.start.column--; count--; } this.selection.setSelectionRange(range); indentString = "\t"; } return this.insert(indentString); }; this.blockIndent = function() { var rows = this.$getSelectedRows(); this.session.indentRows(rows.first, rows.last, "\t"); }; this.blockOutdent = function() { var selection = this.session.getSelection(); this.session.outdentRows(selection.getRange()); }; this.sortLines = function() { var rows = this.$getSelectedRows(); var session = this.session; var lines = []; for (i = rows.first; i <= rows.last; i++) lines.push(session.getLine(i)); lines.sort(function(a, b) { if (a.toLowerCase() < b.toLowerCase()) return -1; if (a.toLowerCase() > b.toLowerCase()) return 1; return 0; }); var deleteRange = new Range(0, 0, 0, 0); for (var i = rows.first; i <= rows.last; i++) { var line = session.getLine(i); deleteRange.start.row = i; deleteRange.end.row = i; deleteRange.end.column = line.length; session.replace(deleteRange, lines[i-rows.first]); } }; this.toggleCommentLines = function() { var state = this.session.getState(this.getCursorPosition().row); var rows = this.$getSelectedRows(); this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last); }; this.toggleBlockComment = function() { var cursor = this.getCursorPosition(); var state = this.session.getState(cursor.row); var range = this.getSelectionRange(); this.session.getMode().toggleBlockComment(state, this.session, range, cursor); }; this.getNumberAt = function(row, column) { var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g; _numberRx.lastIndex = 0; var s = this.session.getLine(row); while (_numberRx.lastIndex < column) { var m = _numberRx.exec(s); if(m.index <= column && m.index+m[0].length >= column){ var number = { value: m[0], start: m.index, end: m.index+m[0].length }; return number; } } return null; }; this.modifyNumber = function(amount) { var row = this.selection.getCursor().row; var column = this.selection.getCursor().column; var charRange = new Range(row, column-1, row, column); var c = this.session.getTextRange(charRange); if (!isNaN(parseFloat(c)) && isFinite(c)) { var nr = this.getNumberAt(row, column); if (nr) { var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end; var decimals = nr.start + nr.value.length - fp; var t = parseFloat(nr.value); t *= Math.pow(10, decimals); if(fp !== nr.end && column < fp){ amount *= Math.pow(10, nr.end - column - 1); } else { amount *= Math.pow(10, nr.end - column); } t += amount; t /= Math.pow(10, decimals); var nnr = t.toFixed(decimals); var replaceRange = new Range(row, nr.start, row, nr.end); this.session.replace(replaceRange, nnr); this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length)); } } }; this.removeLines = function() { var rows = this.$getSelectedRows(); var range; if (rows.first === 0 || rows.last+1 < this.session.getLength()) range = new Range(rows.first, 0, rows.last+1, 0); else 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.duplicateSelection = function() { var sel = this.selection; var doc = this.session; var range = sel.getRange(); var reverse = sel.isBackwards(); if (range.isEmpty()) { var row = range.start.row; doc.duplicateLines(row, row); } else { var point = reverse ? range.start : range.end; var endPoint = doc.insert(point, doc.getTextRange(range), false); range.start = point; range.end = endPoint; sel.setSelectionRange(range, reverse); } }; this.moveLinesDown = function() { this.$moveLines(function(firstRow, lastRow) { return this.session.moveLinesDown(firstRow, lastRow); }); }; this.moveLinesUp = function() { this.$moveLines(function(firstRow, lastRow) { return this.session.moveLinesUp(firstRow, lastRow); }); }; this.moveText = function(range, toPosition, copy) { return this.session.moveText(range, toPosition, copy); }; this.copyLinesUp = function() { this.$moveLines(function(firstRow, lastRow) { this.session.duplicateLines(firstRow, lastRow); return 0; }); }; this.copyLinesDown = function() { this.$moveLines(function(firstRow, lastRow) { return this.session.duplicateLines(firstRow, lastRow); }); }; this.$moveLines = function(mover) { var selection = this.selection; if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) { var range = selection.toOrientedRange(); var rows = this.$getSelectedRows(range); var linesMoved = mover.call(this, rows.first, rows.last); range.moveBy(linesMoved, 0); selection.fromOrientedRange(range); } else { var ranges = selection.rangeList.ranges; selection.rangeList.detach(this.session); for (var i = ranges.length; i--; ) { var rangeIndex = i; var rows = ranges[i].collapseRows(); var last = rows.end.row; var first = rows.start.row; while (i--) { rows = ranges[i].collapseRows(); if (first - rows.end.row <= 1) first = rows.end.row; else break; } i++; var linesMoved = mover.call(this, first, last); while (rangeIndex >= i) { ranges[rangeIndex].moveBy(linesMoved, 0); rangeIndex--; } } selection.fromOrientedRange(selection.ranges[0]); selection.rangeList.attach(this.session); } }; this.$getSelectedRows = function() { var range = this.getSelectionRange().collapseRows(); return { first: this.session.getRowFoldStart(range.start.row), last: this.session.getRowFoldEnd(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.renderer.getFirstVisibleRow(); }; this.getLastVisibleRow = function() { return this.renderer.getLastVisibleRow(); }; this.isRowVisible = function(row) { return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); }; this.isRowFullyVisible = function(row) { return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow()); }; this.$getVisibleRowCount = function() { return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1; }; this.$moveByPage = function(dir, select) { var renderer = this.renderer; var config = this.renderer.layerConfig; var rows = dir * Math.floor(config.height / config.lineHeight); this.$blockScrolling++; if (select === true) { this.selection.$moveSelection(function(){ this.moveCursorBy(rows, 0); }); } else if (select === false) { this.selection.moveCursorBy(rows, 0); this.selection.clearSelection(); } this.$blockScrolling--; var scrollTop = renderer.scrollTop; renderer.scrollBy(0, rows * config.lineHeight); if (select != null) renderer.scrollCursorIntoView(null, 0.5); renderer.animateScrolling(scrollTop); }; this.selectPageDown = function() { this.$moveByPage(1, true); }; this.selectPageUp = function() { this.$moveByPage(-1, true); }; this.gotoPageDown = function() { this.$moveByPage(1, false); }; this.gotoPageUp = function() { this.$moveByPage(-1, false); }; this.scrollPageDown = function() { this.$moveByPage(1); }; this.scrollPageUp = function() { this.$moveByPage(-1); }; this.scrollToRow = function(row) { this.renderer.scrollToRow(row); }; this.scrollToLine = function(line, center, animate, callback) { this.renderer.scrollToLine(line, center, animate, callback); }; this.centerSelection = function() { var range = this.getSelectionRange(); var pos = { row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2), column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2) }; this.renderer.alignCursor(pos, 0.5); }; this.getCursorPosition = function() { return this.selection.getCursor(); }; this.getCursorPositionScreen = function() { return this.session.documentToScreenPosition(this.getCursorPosition()); }; this.getSelectionRange = function() { return this.selection.getRange(); }; this.selectAll = function() { this.$blockScrolling += 1; this.selection.selectAll(); this.$blockScrolling -= 1; }; this.clearSelection = function() { this.selection.clearSelection(); }; this.moveCursorTo = function(row, column) { this.selection.moveCursorTo(row, column); }; this.moveCursorToPosition = function(pos) { this.selection.moveCursorToPosition(pos); }; this.jumpToMatching = function(select, expand) { var cursor = this.getCursorPosition(); var iterator = new TokenIterator(this.session, cursor.row, cursor.column); var prevToken = iterator.getCurrentToken(); var token = prevToken || iterator.stepForward(); if (!token) return; var matchType; var found = false; var depth = {}; var i = cursor.column - token.start; var bracketType; var brackets = { ")": "(", "(": "(", "]": "[", "[": "[", "{": "{", "}": "{" }; do { if (token.value.match(/[{}()\[\]]/g)) { for (; i < token.value.length && !found; i++) { if (!brackets[token.value[i]]) { continue; } bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen"); if (isNaN(depth[bracketType])) { depth[bracketType] = 0; } switch (token.value[i]) { case '(': case '[': case '{': depth[bracketType]++; break; case ')': case ']': case '}': depth[bracketType]--; if (depth[bracketType] === -1) { matchType = 'bracket'; found = true; } break; } } } else if (token && token.type.indexOf('tag-name') !== -1) { if (isNaN(depth[token.value])) { depth[token.value] = 0; } if (prevToken.value === '<') { depth[token.value]++; } else if (prevToken.value === '= 0; --i) { if(this.$tryReplace(ranges[i], replacement)) { replaced++; } } this.selection.setSelectionRange(selection); this.$blockScrolling -= 1; return replaced; }; this.$tryReplace = function(range, replacement) { var input = this.session.getTextRange(range); replacement = this.$search.replace(input, replacement); if (replacement !== null) { range.end = this.session.replace(range, replacement); return range; } else { return null; } }; this.getLastSearchOptions = function() { return this.$search.getOptions(); }; this.find = function(needle, options, animate) { if (!options) options = {}; if (typeof needle == "string" || needle instanceof RegExp) options.needle = needle; else if (typeof needle == "object") oop.mixin(options, needle); var range = this.selection.getRange(); if (options.needle == null) { needle = this.session.getTextRange(range) || this.$search.$options.needle; if (!needle) { range = this.session.getWordRange(range.start.row, range.start.column); needle = this.session.getTextRange(range); } this.$search.set({needle: needle}); } this.$search.set(options); if (!options.start) this.$search.set({start: range}); var newRange = this.$search.find(this.session); if (options.preventScroll) return newRange; if (newRange) { this.revealRange(newRange, animate); return newRange; } if (options.backwards) range.start = range.end; else range.end = range.start; this.selection.setRange(range); }; this.findNext = function(options, animate) { this.find({skipCurrent: true, backwards: false}, options, animate); }; this.findPrevious = function(options, animate) { this.find(options, {skipCurrent: true, backwards: true}, animate); }; this.revealRange = function(range, animate) { this.$blockScrolling += 1; this.session.unfold(range); this.selection.setSelectionRange(range); this.$blockScrolling -= 1; var scrollTop = this.renderer.scrollTop; this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5); if (animate !== false) this.renderer.animateScrolling(scrollTop); }; this.undo = function() { this.$blockScrolling++; this.session.getUndoManager().undo(); this.$blockScrolling--; this.renderer.scrollCursorIntoView(null, 0.5); }; this.redo = function() { this.$blockScrolling++; this.session.getUndoManager().redo(); this.$blockScrolling--; this.renderer.scrollCursorIntoView(null, 0.5); }; this.destroy = function() { this.renderer.destroy(); this._signal("destroy", this); if (this.session) { this.session.destroy(); } }; this.setAutoScrollEditorIntoView = function(enable) { if (!enable) return; var rect; var self = this; var shouldScroll = false; if (!this.$scrollAnchor) this.$scrollAnchor = document.createElement("div"); var scrollAnchor = this.$scrollAnchor; scrollAnchor.style.cssText = "position:absolute"; this.container.insertBefore(scrollAnchor, this.container.firstChild); var onChangeSelection = this.on("changeSelection", function() { shouldScroll = true; }); var onBeforeRender = this.renderer.on("beforeRender", function() { if (shouldScroll) rect = self.renderer.container.getBoundingClientRect(); }); var onAfterRender = this.renderer.on("afterRender", function() { if (shouldScroll && rect && (self.isFocused() || self.searchBox && self.searchBox.isFocused()) ) { var renderer = self.renderer; var pos = renderer.$cursorLayer.$pixelPos; var config = renderer.layerConfig; var top = pos.top - config.offset; if (pos.top >= 0 && top + rect.top < 0) { shouldScroll = true; } else if (pos.top < config.height && pos.top + rect.top + config.lineHeight > window.innerHeight) { shouldScroll = false; } else { shouldScroll = null; } if (shouldScroll != null) { scrollAnchor.style.top = top + "px"; scrollAnchor.style.left = pos.left + "px"; scrollAnchor.style.height = config.lineHeight + "px"; scrollAnchor.scrollIntoView(shouldScroll); } shouldScroll = rect = null; } }); this.setAutoScrollEditorIntoView = function(enable) { if (enable) return; delete this.setAutoScrollEditorIntoView; this.removeEventListener("changeSelection", onChangeSelection); this.renderer.removeEventListener("afterRender", onAfterRender); this.renderer.removeEventListener("beforeRender", onBeforeRender); }; }; this.$resetCursorStyle = function() { var style = this.$cursorStyle || "ace"; var cursorLayer = this.renderer.$cursorLayer; if (!cursorLayer) return; cursorLayer.setSmoothBlinking(/smooth/.test(style)); cursorLayer.isBlinking = !this.$readOnly && style != "wide"; dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style)); }; }).call(Editor.prototype); config.defineOptions(Editor.prototype, "editor", { selectionStyle: { set: function(style) { this.onSelectionChange(); this._signal("changeSelectionStyle", {data: style}); }, initialValue: "line" }, highlightActiveLine: { set: function() {this.$updateHighlightActiveLine();}, initialValue: true }, highlightSelectedWord: { set: function(shouldHighlight) {this.$onSelectionChange();}, initialValue: true }, readOnly: { set: function(readOnly) { this.$resetCursorStyle(); }, initialValue: false }, cursorStyle: { set: function(val) { this.$resetCursorStyle(); }, values: ["ace", "slim", "smooth", "wide"], initialValue: "ace" }, mergeUndoDeltas: { values: [false, true, "always"], initialValue: true }, behavioursEnabled: {initialValue: true}, wrapBehavioursEnabled: {initialValue: true}, autoScrollEditorIntoView: { set: function(val) {this.setAutoScrollEditorIntoView(val)} }, hScrollBarAlwaysVisible: "renderer", vScrollBarAlwaysVisible: "renderer", highlightGutterLine: "renderer", animatedScroll: "renderer", showInvisibles: "renderer", showPrintMargin: "renderer", printMarginColumn: "renderer", printMargin: "renderer", fadeFoldWidgets: "renderer", showFoldWidgets: "renderer", showLineNumbers: "renderer", showGutter: "renderer", displayIndentGuides: "renderer", fontSize: "renderer", fontFamily: "renderer", maxLines: "renderer", minLines: "renderer", scrollPastEnd: "renderer", fixedWidthGutter: "renderer", theme: "renderer", scrollSpeed: "$mouseHandler", dragDelay: "$mouseHandler", dragEnabled: "$mouseHandler", focusTimout: "$mouseHandler", tooltipFollowsMouse: "$mouseHandler", firstLineNumber: "session", overwrite: "session", newLineMode: "session", useWorker: "session", useSoftTabs: "session", tabSize: "session", wrap: "session", foldStyle: "session", mode: "session" }); exports.Editor = Editor; }); ace.define("ace/undomanager",["require","exports","module"], function(require, exports, module) { "use strict"; var UndoManager = function() { this.reset(); }; (function() { this.execute = function(options) { var deltas = options.args[0]; this.$doc = options.args[1]; if (options.merge && this.hasUndo()){ this.dirtyCounter--; deltas = this.$undoStack.pop().concat(deltas); } this.$undoStack.push(deltas); this.$redoStack = []; if (this.dirtyCounter < 0) { this.dirtyCounter = NaN; } this.dirtyCounter++; }; this.undo = function(dontSelect) { var deltas = this.$undoStack.pop(); var undoSelectionRange = null; if (deltas) { undoSelectionRange = this.$doc.undoChanges(deltas, dontSelect); this.$redoStack.push(deltas); this.dirtyCounter--; } return undoSelectionRange; }; this.redo = function(dontSelect) { var deltas = this.$redoStack.pop(); var redoSelectionRange = null; if (deltas) { redoSelectionRange = this.$doc.redoChanges(deltas, dontSelect); this.$undoStack.push(deltas); this.dirtyCounter++; } return redoSelectionRange; }; this.reset = function() { this.$undoStack = []; this.$redoStack = []; this.dirtyCounter = 0; }; this.hasUndo = function() { return this.$undoStack.length > 0; }; this.hasRedo = function() { return this.$redoStack.length > 0; }; this.markClean = function() { this.dirtyCounter = 0; }; this.isClean = function() { return this.dirtyCounter === 0; }; }).call(UndoManager.prototype); exports.UndoManager = UndoManager; }); ace.define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"], function(require, exports, module) { "use strict"; var dom = require("../lib/dom"); var oop = require("../lib/oop"); var lang = require("../lib/lang"); var EventEmitter = require("../lib/event_emitter").EventEmitter; var Gutter = function(parentEl) { this.element = dom.createElement("div"); this.element.className = "ace_layer ace_gutter-layer"; parentEl.appendChild(this.element); this.setShowFoldWidgets(this.$showFoldWidgets); this.gutterWidth = 0; this.$annotations = []; this.$updateAnnotations = this.$updateAnnotations.bind(this); this.$cells = []; }; (function() { oop.implement(this, EventEmitter); this.setSession = function(session) { if (this.session) this.session.removeEventListener("change", this.$updateAnnotations); this.session = session; if (session) session.on("change", this.$updateAnnotations); }; this.addGutterDecoration = function(row, className){ if (window.console) console.warn && console.warn("deprecated use session.addGutterDecoration"); this.session.addGutterDecoration(row, className); }; this.removeGutterDecoration = function(row, className){ if (window.console) console.warn && console.warn("deprecated use session.removeGutterDecoration"); this.session.removeGutterDecoration(row, className); }; this.setAnnotations = function(annotations) { this.$annotations = []; for (var i = 0; i < annotations.length; i++) { var annotation = annotations[i]; var row = annotation.row; var rowInfo = this.$annotations[row]; if (!rowInfo) rowInfo = this.$annotations[row] = {text: []}; var annoText = annotation.text; annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || ""; if (rowInfo.text.indexOf(annoText) === -1) rowInfo.text.push(annoText); var type = annotation.type; if (type == "error") rowInfo.className = " ace_error"; else if (type == "warning" && rowInfo.className != " ace_error") rowInfo.className = " ace_warning"; else if (type == "info" && (!rowInfo.className)) rowInfo.className = " ace_info"; } }; this.$updateAnnotations = function (e) { if (!this.$annotations.length) return; var delta = e.data; var range = delta.range; var firstRow = range.start.row; var len = range.end.row - firstRow; if (len === 0) { } else if (delta.action == "removeText" || delta.action == "removeLines") { this.$annotations.splice(firstRow, len + 1, null); } else { var args = new Array(len + 1); args.unshift(firstRow, 1); this.$annotations.splice.apply(this.$annotations, args); } }; this.update = function(config) { var session = this.session; var firstRow = config.firstRow; var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar session.getLength() - 1); var fold = session.getNextFoldLine(firstRow); var foldStart = fold ? fold.start.row : Infinity; var foldWidgets = this.$showFoldWidgets && session.foldWidgets; var breakpoints = session.$breakpoints; var decorations = session.$decorations; var firstLineNumber = session.$firstLineNumber; var lastLineNumber = 0; var gutterRenderer = session.gutterRenderer || this.$renderer; var cell = null; var index = -1; var row = firstRow; while (true) { if (row > foldStart) { row = fold.end.row + 1; fold = session.getNextFoldLine(row, fold); foldStart = fold ? fold.start.row : Infinity; } if (row > lastRow) { while (this.$cells.length > index + 1) { cell = this.$cells.pop(); this.element.removeChild(cell.element); } break; } cell = this.$cells[++index]; if (!cell) { cell = {element: null, textNode: null, foldWidget: null}; cell.element = dom.createElement("div"); cell.textNode = document.createTextNode(''); cell.element.appendChild(cell.textNode); this.element.appendChild(cell.element); this.$cells[index] = cell; } var className = "ace_gutter-cell "; if (breakpoints[row]) className += breakpoints[row]; if (decorations[row]) className += decorations[row]; if (this.$annotations[row]) className += this.$annotations[row].className; if (cell.element.className != className) cell.element.className = className; var height = session.getRowLength(row) * config.lineHeight + "px"; if (height != cell.element.style.height) cell.element.style.height = height; if (foldWidgets) { var c = foldWidgets[row]; if (c == null) c = foldWidgets[row] = session.getFoldWidget(row); } if (c) { if (!cell.foldWidget) { cell.foldWidget = dom.createElement("span"); cell.element.appendChild(cell.foldWidget); } var className = "ace_fold-widget ace_" + c; if (c == "start" && row == foldStart && row < fold.end.row) className += " ace_closed"; else className += " ace_open"; if (cell.foldWidget.className != className) cell.foldWidget.className = className; var height = config.lineHeight + "px"; if (cell.foldWidget.style.height != height) cell.foldWidget.style.height = height; } else { if (cell.foldWidget) { cell.element.removeChild(cell.foldWidget); cell.foldWidget = null; } } var text = lastLineNumber = gutterRenderer ? gutterRenderer.getText(session, row) : row + firstLineNumber; if (text != cell.textNode.data) cell.textNode.data = text; row++; } this.element.style.height = config.minHeight + "px"; if (this.$fixedWidth || session.$useWrapMode) lastLineNumber = session.getLength() + firstLineNumber; var gutterWidth = gutterRenderer ? gutterRenderer.getWidth(session, lastLineNumber, config) : lastLineNumber.toString().length * config.characterWidth; var padding = this.$padding || this.$computePadding(); gutterWidth += padding.left + padding.right; if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) { this.gutterWidth = gutterWidth; this.element.style.width = Math.ceil(this.gutterWidth) + "px"; this._emit("changeGutterWidth", gutterWidth); } }; this.$fixedWidth = false; this.$showLineNumbers = true; this.$renderer = ""; this.setShowLineNumbers = function(show) { this.$renderer = !show && { getWidth: function() {return ""}, getText: function() {return ""} }; }; this.getShowLineNumbers = function() { return this.$showLineNumbers; }; this.$showFoldWidgets = true; this.setShowFoldWidgets = function(show) { if (show) dom.addCssClass(this.element, "ace_folding-enabled"); else dom.removeCssClass(this.element, "ace_folding-enabled"); this.$showFoldWidgets = show; this.$padding = null; }; this.getShowFoldWidgets = function() { return this.$showFoldWidgets; }; this.$computePadding = function() { if (!this.element.firstChild) return {left: 0, right: 0}; var style = dom.computedStyle(this.element.firstChild); this.$padding = {}; this.$padding.left = parseInt(style.paddingLeft) + 1 || 0; this.$padding.right = parseInt(style.paddingRight) || 0; return this.$padding; }; this.getRegion = function(point) { var padding = this.$padding || this.$computePadding(); var rect = this.element.getBoundingClientRect(); if (point.x < padding.left + rect.left) return "markers"; if (this.$showFoldWidgets && point.x > rect.right - padding.right) return "foldWidgets"; }; }).call(Gutter.prototype); exports.Gutter = Gutter; }); ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"], function(require, exports, module) { "use strict"; var Range = require("../range").Range; var dom = require("../lib/dom"); var Marker = function(parentEl) { this.element = dom.createElement("div"); this.element.className = "ace_layer ace_marker-layer"; parentEl.appendChild(this.element); }; (function() { this.$padding = 0; this.setPadding = function(padding) { this.$padding = padding; }; this.setSession = function(session) { this.session = session; }; this.setMarkers = function(markers) { this.markers = markers; }; this.update = function(config) { var config = config || this.config; if (!config) return; this.config = config; var html = []; for (var key in this.markers) { var marker = this.markers[key]; if (!marker.range) { marker.update(html, this, this.session, config); continue; } var range = marker.range.clipRows(config.firstRow, config.lastRow); if (range.isEmpty()) continue; range = range.toScreenRange(this.session); if (marker.renderer) { var top = this.$getTop(range.start.row, config); var left = this.$padding + range.start.column * config.characterWidth; marker.renderer(html, range, left, top, config); } else if (marker.type == "fullLine") { this.drawFullLineMarker(html, range, marker.clazz, config); } else if (marker.type == "screenLine") { this.drawScreenLineMarker(html, range, marker.clazz, config); } else if (range.isMultiLine()) { if (marker.type == "text") this.drawTextMarker(html, range, marker.clazz, config); else this.drawMultiLineMarker(html, range, marker.clazz, config); } else { this.drawSingleLineMarker(html, range, marker.clazz + " ace_start", config); } } this.element.innerHTML = html.join(""); }; this.$getTop = function(row, layerConfig) { return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight; }; this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig, extraStyle) { var row = range.start.row; var lineRange = new Range( row, range.start.column, row, this.session.getScreenLastRowColumn(row) ); this.drawSingleLineMarker(stringBuilder, lineRange, clazz + " ace_start", layerConfig, 1, extraStyle); row = range.end.row; lineRange = new Range(row, 0, row, range.end.column); this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 0, extraStyle); for (row = range.start.row + 1; row < range.end.row; row++) { lineRange.start.row = row; lineRange.end.row = row; lineRange.end.column = this.session.getScreenLastRowColumn(row); this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1, extraStyle); } }; this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { var padding = this.$padding; var height = config.lineHeight; var top = this.$getTop(range.start.row, config); var left = padding + range.start.column * config.characterWidth; extraStyle = extraStyle || ""; stringBuilder.push( "
" ); top = this.$getTop(range.end.row, config); var width = range.end.column * config.characterWidth; stringBuilder.push( "
" ); height = (range.end.row - range.start.row - 1) * config.lineHeight; if (height < 0) return; top = this.$getTop(range.start.row + 1, config); stringBuilder.push( "
" ); }; this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) { var height = config.lineHeight; var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth; var top = this.$getTop(range.start.row, config); var left = this.$padding + range.start.column * config.characterWidth; stringBuilder.push( "
" ); }; this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { var top = this.$getTop(range.start.row, config); var height = config.lineHeight; if (range.start.row != range.end.row) height += this.$getTop(range.end.row, config) - top; stringBuilder.push( "
" ); }; this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { var top = this.$getTop(range.start.row, config); var height = config.lineHeight; stringBuilder.push( "
" ); }; }).call(Marker.prototype); exports.Marker = Marker; }); ace.define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var dom = require("../lib/dom"); var lang = require("../lib/lang"); var useragent = require("../lib/useragent"); var EventEmitter = require("../lib/event_emitter").EventEmitter; var Text = function(parentEl) { this.element = dom.createElement("div"); this.element.className = "ace_layer ace_text-layer"; parentEl.appendChild(this.element); this.$updateEolChar = this.$updateEolChar.bind(this); }; (function() { oop.implement(this, EventEmitter); this.EOF_CHAR = "\xB6"; this.EOL_CHAR_LF = "\xAC"; this.EOL_CHAR_CRLF = "\xa4"; this.EOL_CHAR = this.EOL_CHAR_LF; this.TAB_CHAR = "\u2192"; //"\u21E5"; this.SPACE_CHAR = "\xB7"; this.$padding = 0; this.$updateEolChar = function() { var EOL_CHAR = this.session.doc.getNewLineCharacter() == "\n" ? this.EOL_CHAR_LF : this.EOL_CHAR_CRLF; if (this.EOL_CHAR != EOL_CHAR) { this.EOL_CHAR = EOL_CHAR; return true; } } this.setPadding = function(padding) { this.$padding = padding; this.element.style.padding = "0 " + padding + "px"; }; this.getLineHeight = function() { return this.$fontMetrics.$characterSize.height || 0; }; this.getCharacterWidth = function() { return this.$fontMetrics.$characterSize.width || 0; }; this.$setFontMetrics = function(measure) { this.$fontMetrics = measure; this.$fontMetrics.on("changeCharacterSize", function(e) { this._signal("changeCharacterSize", e); }.bind(this)); this.$pollSizeChanges(); } this.checkForSizeChanges = function() { this.$fontMetrics.checkForSizeChanges(); }; this.$pollSizeChanges = function() { return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges(); }; this.setSession = function(session) { this.session = session; if (session) this.$computeTabString(); }; this.showInvisibles = false; this.setShowInvisibles = function(showInvisibles) { if (this.showInvisibles == showInvisibles) return false; this.showInvisibles = showInvisibles; this.$computeTabString(); return true; }; this.displayIndentGuides = true; this.setDisplayIndentGuides = function(display) { if (this.displayIndentGuides == display) return false; this.displayIndentGuides = display; this.$computeTabString(); return true; }; this.$tabStrings = []; this.onChangeTabSize = this.$computeTabString = function() { var tabSize = this.session.getTabSize(); this.tabSize = tabSize; var tabStr = this.$tabStrings = [0]; for (var i = 1; i < tabSize + 1; i++) { if (this.showInvisibles) { tabStr.push("" + this.TAB_CHAR + lang.stringRepeat("\xa0", i - 1) + ""); } else { tabStr.push(lang.stringRepeat("\xa0", i)); } } if (this.displayIndentGuides) { this.$indentGuideRe = /\s\S| \t|\t |\s$/; var className = "ace_indent-guide"; var spaceClass = ""; var tabClass = ""; if (this.showInvisibles) { className += " ace_invisible"; spaceClass = " ace_invisible_space"; tabClass = " ace_invisible_tab"; var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize); var tabContent = this.TAB_CHAR + lang.stringRepeat("\xa0", this.tabSize - 1); } else{ var spaceContent = lang.stringRepeat("\xa0", this.tabSize); var tabContent = spaceContent; } this.$tabStrings[" "] = "" + spaceContent + ""; this.$tabStrings["\t"] = "" + tabContent + ""; } }; this.updateLines = function(config, firstRow, lastRow) { if (this.config.lastRow != config.lastRow || this.config.firstRow != config.firstRow) { this.scrollLines(config); } this.config = config; var first = Math.max(firstRow, config.firstRow); var last = Math.min(lastRow, config.lastRow); var lineElements = this.element.childNodes; var lineElementsIdx = 0; for (var row = config.firstRow; row < first; row++) { var foldLine = this.session.getFoldLine(row); if (foldLine) { if (foldLine.containsRow(first)) { first = foldLine.start.row; break; } else { row = foldLine.end.row; } } lineElementsIdx ++; } var row = first; var foldLine = this.session.getNextFoldLine(row); var foldStart = foldLine ? foldLine.start.row : Infinity; while (true) { if (row > foldStart) { row = foldLine.end.row+1; foldLine = this.session.getNextFoldLine(row, foldLine); foldStart = foldLine ? foldLine.start.row :Infinity; } if (row > last) break; var lineElement = lineElements[lineElementsIdx++]; if (lineElement) { var html = []; this.$renderLine( html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false ); lineElement.style.height = config.lineHeight * this.session.getRowLength(row) + "px"; lineElement.innerHTML = html.join(""); } row++; } }; this.scrollLines = function(config) { var oldConfig = this.config; this.config = config; if (!oldConfig || oldConfig.lastRow < config.firstRow) return this.update(config); if (config.lastRow < oldConfig.firstRow) return this.update(config); var el = this.element; if (oldConfig.firstRow < config.firstRow) for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--) el.removeChild(el.firstChild); if (oldConfig.lastRow > config.lastRow) for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--) el.removeChild(el.lastChild); if (config.firstRow < oldConfig.firstRow) { var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1); if (el.firstChild) el.insertBefore(fragment, el.firstChild); else el.appendChild(fragment); } if (config.lastRow > oldConfig.lastRow) { var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow); el.appendChild(fragment); } }; this.$renderLinesFragment = function(config, firstRow, lastRow) { var fragment = this.element.ownerDocument.createDocumentFragment(); var row = firstRow; var foldLine = this.session.getNextFoldLine(row); var foldStart = foldLine ? foldLine.start.row : Infinity; while (true) { if (row > foldStart) { row = foldLine.end.row+1; foldLine = this.session.getNextFoldLine(row, foldLine); foldStart = foldLine ? foldLine.start.row : Infinity; } if (row > lastRow) break; var container = dom.createElement("div"); var html = []; this.$renderLine(html, row, false, row == foldStart ? foldLine : false); container.innerHTML = html.join(""); if (this.$useLineGroups()) { container.className = 'ace_line_group'; fragment.appendChild(container); container.style.height = config.lineHeight * this.session.getRowLength(row) + "px"; } else { while(container.firstChild) fragment.appendChild(container.firstChild); } row++; } return fragment; }; this.update = function(config) { this.config = config; var html = []; var firstRow = config.firstRow, lastRow = config.lastRow; var row = firstRow; var foldLine = this.session.getNextFoldLine(row); var foldStart = foldLine ? foldLine.start.row : Infinity; while (true) { if (row > foldStart) { row = foldLine.end.row+1; foldLine = this.session.getNextFoldLine(row, foldLine); foldStart = foldLine ? foldLine.start.row :Infinity; } if (row > lastRow) break; if (this.$useLineGroups()) html.push("
") this.$renderLine(html, row, false, row == foldStart ? foldLine : false); if (this.$useLineGroups()) html.push("
"); // end the line group row++; } this.element.innerHTML = html.join(""); }; this.$textToken = { "text": true, "rparen": true, "lparen": true }; this.$renderToken = function(stringBuilder, screenColumn, token, value) { var self = this; var replaceReg = /\t|&|<|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g; var replaceFunc = function(c, a, b, tabIdx, idx4) { if (a) { return self.showInvisibles ? "" + lang.stringRepeat(self.SPACE_CHAR, c.length) + "" : lang.stringRepeat("\xa0", c.length); } else if (c == "&") { return "&"; } else if (c == "<") { return "<"; } else if (c == "\t") { var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx); screenColumn += tabSize - 1; return self.$tabStrings[tabSize]; } else if (c == "\u3000") { var classToUse = self.showInvisibles ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk"; var space = self.showInvisibles ? self.SPACE_CHAR : ""; screenColumn += 1; return "" + space + ""; } else if (b) { return "" + self.SPACE_CHAR + ""; } else { screenColumn += 1; return "" + c + ""; } }; var output = value.replace(replaceReg, replaceFunc); if (!this.$textToken[token.type]) { var classes = "ace_" + token.type.replace(/\./g, " ace_"); var style = ""; if (token.type == "fold") style = " style='width:" + (token.value.length * this.config.characterWidth) + "px;' "; stringBuilder.push("", output, ""); } else { stringBuilder.push(output); } return screenColumn + value.length; }; this.renderIndentGuide = function(stringBuilder, value, max) { var cols = value.search(this.$indentGuideRe); if (cols <= 0 || cols >= max) return value; if (value[0] == " ") { cols -= cols % this.tabSize; stringBuilder.push(lang.stringRepeat(this.$tabStrings[" "], cols/this.tabSize)); return value.substr(cols); } else if (value[0] == "\t") { stringBuilder.push(lang.stringRepeat(this.$tabStrings["\t"], cols)); return value.substr(cols); } return value; }; this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) { var chars = 0; var split = 0; var splitChars = splits[0]; var screenColumn = 0; for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; var value = token.value; if (i == 0 && this.displayIndentGuides) { chars = value.length; value = this.renderIndentGuide(stringBuilder, value, splitChars); if (!value) continue; chars -= value.length; } if (chars + value.length < splitChars) { screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); chars += value.length; } else { while (chars + value.length >= splitChars) { screenColumn = this.$renderToken( stringBuilder, screenColumn, token, value.substring(0, splitChars - chars) ); value = value.substring(splitChars - chars); chars = splitChars; if (!onlyContents) { stringBuilder.push("", "
" ); } split ++; screenColumn = 0; splitChars = splits[split] || Number.MAX_VALUE; } if (value.length != 0) { chars += value.length; screenColumn = this.$renderToken( stringBuilder, screenColumn, token, value ); } } } }; this.$renderSimpleLine = function(stringBuilder, tokens) { var screenColumn = 0; var token = tokens[0]; var value = token.value; if (this.displayIndentGuides) value = this.renderIndentGuide(stringBuilder, value); if (value) screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); for (var i = 1; i < tokens.length; i++) { token = tokens[i]; value = token.value; screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); } }; this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) { if (!foldLine && foldLine != false) foldLine = this.session.getFoldLine(row); if (foldLine) var tokens = this.$getFoldLineTokens(row, foldLine); else var tokens = this.session.getTokens(row); if (!onlyContents) { stringBuilder.push( "
" ); } if (tokens.length) { var splits = this.session.getRowSplitData(row); if (splits && splits.length) this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents); else this.$renderSimpleLine(stringBuilder, tokens); } if (this.showInvisibles) { if (foldLine) row = foldLine.end.row stringBuilder.push( "", row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR, "" ); } if (!onlyContents) stringBuilder.push("
"); }; this.$getFoldLineTokens = function(row, foldLine) { var session = this.session; var renderTokens = []; function addTokens(tokens, from, to) { var idx = 0, col = 0; while ((col + tokens[idx].value.length) < from) { col += tokens[idx].value.length; idx++; if (idx == tokens.length) return; } if (col != from) { var value = tokens[idx].value.substring(from - col); if (value.length > (to - from)) value = value.substring(0, to - from); renderTokens.push({ type: tokens[idx].type, value: value }); col = from + value.length; idx += 1; } while (col < to && idx < tokens.length) { var value = tokens[idx].value; if (value.length + col > to) { renderTokens.push({ type: tokens[idx].type, value: value.substring(0, to - col) }); } else renderTokens.push(tokens[idx]); col += value.length; idx += 1; } } var tokens = session.getTokens(row); foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) { if (placeholder != null) { renderTokens.push({ type: "fold", value: placeholder }); } else { if (isNewRow) tokens = session.getTokens(row); if (tokens.length) addTokens(tokens, lastColumn, column); } }, foldLine.end.row, this.session.getLine(foldLine.end.row).length); return renderTokens; }; this.$useLineGroups = function() { return this.session.getUseWrapMode(); }; this.destroy = function() { clearInterval(this.$pollSizeChangesTimer); if (this.$measureNode) this.$measureNode.parentNode.removeChild(this.$measureNode); delete this.$measureNode; }; }).call(Text.prototype); exports.Text = Text; }); ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"], function(require, exports, module) { "use strict"; var dom = require("../lib/dom"); var IE8; var Cursor = function(parentEl) { this.element = dom.createElement("div"); this.element.className = "ace_layer ace_cursor-layer"; parentEl.appendChild(this.element); if (IE8 === undefined) IE8 = "opacity" in this.element; this.isVisible = false; this.isBlinking = true; this.blinkInterval = 1000; this.smoothBlinking = false; this.cursors = []; this.cursor = this.addCursor(); dom.addCssClass(this.element, "ace_hidden-cursors"); this.$updateCursors = this.$updateVisibility.bind(this); }; (function() { this.$updateVisibility = function(val) { var cursors = this.cursors; for (var i = cursors.length; i--; ) cursors[i].style.visibility = val ? "" : "hidden"; }; this.$updateOpacity = function(val) { var cursors = this.cursors; for (var i = cursors.length; i--; ) cursors[i].style.opacity = val ? "" : "0"; }; this.$padding = 0; this.setPadding = function(padding) { this.$padding = padding; }; this.setSession = function(session) { this.session = session; }; this.setBlinking = function(blinking) { if (blinking != this.isBlinking){ this.isBlinking = blinking; this.restartTimer(); } }; this.setBlinkInterval = function(blinkInterval) { if (blinkInterval != this.blinkInterval){ this.blinkInterval = blinkInterval; this.restartTimer(); } }; this.setSmoothBlinking = function(smoothBlinking) { if (smoothBlinking != this.smoothBlinking && !IE8) { this.smoothBlinking = smoothBlinking; dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking); this.$updateCursors(true); this.$updateCursors = (smoothBlinking ? this.$updateOpacity : this.$updateVisibility).bind(this); this.restartTimer(); } }; this.addCursor = function() { var el = dom.createElement("div"); el.className = "ace_cursor"; this.element.appendChild(el); this.cursors.push(el); return el; }; this.removeCursor = function() { if (this.cursors.length > 1) { var el = this.cursors.pop(); el.parentNode.removeChild(el); return el; } }; this.hideCursor = function() { this.isVisible = false; dom.addCssClass(this.element, "ace_hidden-cursors"); this.restartTimer(); }; this.showCursor = function() { this.isVisible = true; dom.removeCssClass(this.element, "ace_hidden-cursors"); this.restartTimer(); }; this.restartTimer = function() { var update = this.$updateCursors; clearInterval(this.intervalId); clearTimeout(this.timeoutId); if (this.smoothBlinking) { dom.removeCssClass(this.element, "ace_smooth-blinking"); } update(true); if (!this.isBlinking || !this.blinkInterval || !this.isVisible) return; if (this.smoothBlinking) { setTimeout(function(){ dom.addCssClass(this.element, "ace_smooth-blinking"); }.bind(this)); } var blink = function(){ this.timeoutId = setTimeout(function() { update(false); }, 0.6 * this.blinkInterval); }.bind(this); this.intervalId = setInterval(function() { update(true); blink(); }, this.blinkInterval); blink(); }; this.getPixelPosition = function(position, onScreen) { if (!this.config || !this.session) return {left : 0, top : 0}; if (!position) position = this.session.selection.getCursor(); var pos = this.session.documentToScreenPosition(position); var cursorLeft = this.$padding + pos.column * this.config.characterWidth; var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * this.config.lineHeight; return {left : cursorLeft, top : cursorTop}; }; this.update = function(config) { this.config = config; var selections = this.session.$selectionMarkers; var i = 0, cursorIndex = 0; if (selections === undefined || selections.length === 0){ selections = [{cursor: null}]; } for (var i = 0, n = selections.length; i < n; i++) { var pixelPos = this.getPixelPosition(selections[i].cursor, true); if ((pixelPos.top > config.height + config.offset || pixelPos.top < 0) && i > 1) { continue; } var style = (this.cursors[cursorIndex++] || this.addCursor()).style; style.left = pixelPos.left + "px"; style.top = pixelPos.top + "px"; style.width = config.characterWidth + "px"; style.height = config.lineHeight + "px"; } while (this.cursors.length > cursorIndex) this.removeCursor(); var overwrite = this.session.getOverwrite(); this.$setOverwrite(overwrite); this.$pixelPos = pixelPos; this.restartTimer(); }; this.$setOverwrite = function(overwrite) { if (overwrite != this.overwrite) { this.overwrite = overwrite; if (overwrite) dom.addCssClass(this.element, "ace_overwrite-cursors"); else dom.removeCssClass(this.element, "ace_overwrite-cursors"); } }; this.destroy = function() { clearInterval(this.intervalId); clearTimeout(this.timeoutId); }; }).call(Cursor.prototype); exports.Cursor = Cursor; }); ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var dom = require("./lib/dom"); var event = require("./lib/event"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var ScrollBar = function(parent) { this.element = dom.createElement("div"); this.element.className = "ace_scrollbar ace_scrollbar" + this.classSuffix; this.inner = dom.createElement("div"); this.inner.className = "ace_scrollbar-inner"; this.element.appendChild(this.inner); parent.appendChild(this.element); this.setVisible(false); this.skipEvent = false; event.addListener(this.element, "scroll", this.onScroll.bind(this)); event.addListener(this.element, "mousedown", event.preventDefault); }; (function() { oop.implement(this, EventEmitter); this.setVisible = function(isVisible) { this.element.style.display = isVisible ? "" : "none"; this.isVisible = isVisible; }; }).call(ScrollBar.prototype); var VScrollBar = function(parent, renderer) { ScrollBar.call(this, parent); this.scrollTop = 0; renderer.$scrollbarWidth = this.width = dom.scrollbarWidth(parent.ownerDocument); this.inner.style.width = this.element.style.width = (this.width || 15) + 5 + "px"; }; oop.inherits(VScrollBar, ScrollBar); (function() { this.classSuffix = '-v'; this.onScroll = function() { if (!this.skipEvent) { this.scrollTop = this.element.scrollTop; this._emit("scroll", {data: this.scrollTop}); } this.skipEvent = false; }; this.getWidth = function() { return this.isVisible ? this.width : 0; }; this.setHeight = function(height) { this.element.style.height = height + "px"; }; this.setInnerHeight = function(height) { this.inner.style.height = height + "px"; }; this.setScrollHeight = function(height) { this.inner.style.height = height + "px"; }; this.setScrollTop = function(scrollTop) { if (this.scrollTop != scrollTop) { this.skipEvent = true; this.scrollTop = this.element.scrollTop = scrollTop; } }; }).call(VScrollBar.prototype); var HScrollBar = function(parent, renderer) { ScrollBar.call(this, parent); this.scrollLeft = 0; this.height = renderer.$scrollbarWidth; this.inner.style.height = this.element.style.height = (this.height || 15) + 5 + "px"; }; oop.inherits(HScrollBar, ScrollBar); (function() { this.classSuffix = '-h'; this.onScroll = function() { if (!this.skipEvent) { this.scrollLeft = this.element.scrollLeft; this._emit("scroll", {data: this.scrollLeft}); } this.skipEvent = false; }; this.getHeight = function() { return this.isVisible ? this.height : 0; }; this.setWidth = function(width) { this.element.style.width = width + "px"; }; this.setInnerWidth = function(width) { this.inner.style.width = width + "px"; }; this.setScrollWidth = function(width) { this.inner.style.width = width + "px"; }; this.setScrollLeft = function(scrollLeft) { if (this.scrollLeft != scrollLeft) { this.skipEvent = true; this.scrollLeft = this.element.scrollLeft = scrollLeft; } }; }).call(HScrollBar.prototype); exports.ScrollBar = VScrollBar; // backward compatibility exports.ScrollBarV = VScrollBar; // backward compatibility exports.ScrollBarH = HScrollBar; // backward compatibility exports.VScrollBar = VScrollBar; exports.HScrollBar = HScrollBar; }); ace.define("ace/renderloop",["require","exports","module","ace/lib/event"], function(require, exports, module) { "use strict"; var event = require("./lib/event"); var RenderLoop = function(onRender, win) { this.onRender = onRender; this.pending = false; this.changes = 0; this.window = win || window; }; (function() { this.schedule = function(change) { this.changes = this.changes | change; if (!this.pending && this.changes) { this.pending = true; var _self = this; event.nextFrame(function() { _self.pending = false; var changes; while (changes = _self.changes) { _self.changes = 0; _self.onRender(changes); } }, this.window); } }; }).call(RenderLoop.prototype); exports.RenderLoop = RenderLoop; }); ace.define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"], function(require, exports, module) { var oop = require("../lib/oop"); var dom = require("../lib/dom"); var lang = require("../lib/lang"); var useragent = require("../lib/useragent"); var EventEmitter = require("../lib/event_emitter").EventEmitter; var CHAR_COUNT = 0; var FontMetrics = exports.FontMetrics = function(parentEl, interval) { this.el = dom.createElement("div"); this.$setMeasureNodeStyles(this.el.style, true); this.$main = dom.createElement("div"); this.$setMeasureNodeStyles(this.$main.style); this.$measureNode = dom.createElement("div"); this.$setMeasureNodeStyles(this.$measureNode.style); this.el.appendChild(this.$main); this.el.appendChild(this.$measureNode); parentEl.appendChild(this.el); if (!CHAR_COUNT) this.$testFractionalRect(); this.$measureNode.innerHTML = lang.stringRepeat("X", CHAR_COUNT); this.$characterSize = {width: 0, height: 0}; this.checkForSizeChanges(); }; (function() { oop.implement(this, EventEmitter); this.$characterSize = {width: 0, height: 0}; this.$testFractionalRect = function() { var el = dom.createElement("div"); this.$setMeasureNodeStyles(el.style); el.style.width = "0.2px"; document.documentElement.appendChild(el); var w = el.getBoundingClientRect().width; if (w > 0 && w < 1) CHAR_COUNT = 50; else CHAR_COUNT = 100; el.parentNode.removeChild(el); }; this.$setMeasureNodeStyles = function(style, isRoot) { style.width = style.height = "auto"; style.left = style.top = "-100px"; style.visibility = "hidden"; style.position = "fixed"; style.whiteSpace = "pre"; if (useragent.isIE < 8) { style["font-family"] = "inherit"; } else { style.font = "inherit"; } style.overflow = isRoot ? "hidden" : "visible"; }; this.checkForSizeChanges = function() { var size = this.$measureSizes(); if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) { this.$measureNode.style.fontWeight = "bold"; var boldSize = this.$measureSizes(); this.$measureNode.style.fontWeight = ""; this.$characterSize = size; this.charSizes = Object.create(null); this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height; this._emit("changeCharacterSize", {data: size}); } }; this.$pollSizeChanges = function() { if (this.$pollSizeChangesTimer) return this.$pollSizeChangesTimer; var self = this; return this.$pollSizeChangesTimer = setInterval(function() { self.checkForSizeChanges(); }, 500); }; this.setPolling = function(val) { if (val) { this.$pollSizeChanges(); } else { if (this.$pollSizeChangesTimer) this.$pollSizeChangesTimer; } }; this.$measureSizes = function() { if (CHAR_COUNT === 50) { var rect = null; try { rect = this.$measureNode.getBoundingClientRect(); } catch(e) { rect = {width: 0, height:0 }; }; var size = { height: rect.height, width: rect.width / CHAR_COUNT }; } else { var size = { height: this.$measureNode.clientHeight, width: this.$measureNode.clientWidth / CHAR_COUNT }; } if (size.width === 0 || size.height === 0) return null; return size; }; this.$measureCharWidth = function(ch) { this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT); var rect = this.$main.getBoundingClientRect(); return rect.width / CHAR_COUNT; }; this.getCharacterWidth = function(ch) { var w = this.charSizes[ch]; if (w === undefined) { this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width; } return w; }; this.destroy = function() { clearInterval(this.$pollSizeChangesTimer); if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el); }; }).call(FontMetrics.prototype); }); ace.define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/lib/useragent","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var dom = require("./lib/dom"); var config = require("./config"); var useragent = require("./lib/useragent"); var GutterLayer = require("./layer/gutter").Gutter; var MarkerLayer = require("./layer/marker").Marker; var TextLayer = require("./layer/text").Text; var CursorLayer = require("./layer/cursor").Cursor; var HScrollBar = require("./scrollbar").HScrollBar; var VScrollBar = require("./scrollbar").VScrollBar; var RenderLoop = require("./renderloop").RenderLoop; var FontMetrics = require("./layer/font_metrics").FontMetrics; var EventEmitter = require("./lib/event_emitter").EventEmitter; var editorCss = ".ace_editor {\ position: relative;\ overflow: hidden;\ font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\ direction: ltr;\ }\ .ace_scroller {\ position: absolute;\ overflow: hidden;\ top: 0;\ bottom: 0;\ background-color: inherit;\ -ms-user-select: none;\ -moz-user-select: none;\ -webkit-user-select: none;\ user-select: none;\ cursor: text;\ }\ .ace_content {\ position: absolute;\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ min-width: 100%;\ }\ .ace_dragging .ace_scroller:before{\ position: absolute;\ top: 0;\ left: 0;\ right: 0;\ bottom: 0;\ content: '';\ background: rgba(250, 250, 250, 0.01);\ z-index: 1000;\ }\ .ace_dragging.ace_dark .ace_scroller:before{\ background: rgba(0, 0, 0, 0.01);\ }\ .ace_selecting, .ace_selecting * {\ cursor: text !important;\ }\ .ace_gutter {\ position: absolute;\ overflow : hidden;\ width: auto;\ top: 0;\ bottom: 0;\ left: 0;\ cursor: default;\ z-index: 4;\ -ms-user-select: none;\ -moz-user-select: none;\ -webkit-user-select: none;\ user-select: none;\ }\ .ace_gutter-active-line {\ position: absolute;\ left: 0;\ right: 0;\ }\ .ace_scroller.ace_scroll-left {\ box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\ }\ .ace_gutter-cell {\ padding-left: 19px;\ padding-right: 6px;\ background-repeat: no-repeat;\ }\ .ace_gutter-cell.ace_error {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\");\ background-repeat: no-repeat;\ background-position: 2px center;\ }\ .ace_gutter-cell.ace_warning {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\");\ background-position: 2px center;\ }\ .ace_gutter-cell.ace_info {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");\ background-position: 2px center;\ }\ .ace_dark .ace_gutter-cell.ace_info {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");\ }\ .ace_scrollbar {\ position: absolute;\ right: 0;\ bottom: 0;\ z-index: 6;\ }\ .ace_scrollbar-inner {\ position: absolute;\ cursor: text;\ left: 0;\ top: 0;\ }\ .ace_scrollbar-v{\ overflow-x: hidden;\ overflow-y: scroll;\ top: 0;\ }\ .ace_scrollbar-h {\ overflow-x: scroll;\ overflow-y: hidden;\ left: 0;\ }\ .ace_print-margin {\ position: absolute;\ height: 100%;\ }\ .ace_text-input {\ position: absolute;\ z-index: 0;\ width: 0.5em;\ height: 1em;\ opacity: 0;\ background: transparent;\ -moz-appearance: none;\ appearance: none;\ border: none;\ resize: none;\ outline: none;\ overflow: hidden;\ font: inherit;\ padding: 0 1px;\ margin: 0 -1px;\ text-indent: -1em;\ -ms-user-select: text;\ -moz-user-select: text;\ -webkit-user-select: text;\ user-select: text;\ }\ .ace_text-input.ace_composition {\ background: inherit;\ color: inherit;\ z-index: 1000;\ opacity: 1;\ text-indent: 0;\ }\ .ace_layer {\ z-index: 1;\ position: absolute;\ overflow: hidden;\ white-space: pre;\ height: 100%;\ width: 100%;\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ pointer-events: none;\ }\ .ace_gutter-layer {\ position: relative;\ width: auto;\ text-align: right;\ pointer-events: auto;\ }\ .ace_text-layer {\ font: inherit !important;\ }\ .ace_cjk {\ display: inline-block;\ text-align: center;\ }\ .ace_cursor-layer {\ z-index: 4;\ }\ .ace_cursor {\ z-index: 4;\ position: absolute;\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ border-left: 2px solid\ }\ .ace_slim-cursors .ace_cursor {\ border-left-width: 1px;\ }\ .ace_overwrite-cursors .ace_cursor {\ border-left-width: 0;\ border-bottom: 1px solid;\ }\ .ace_hidden-cursors .ace_cursor {\ opacity: 0.2;\ }\ .ace_smooth-blinking .ace_cursor {\ -webkit-transition: opacity 0.18s;\ transition: opacity 0.18s;\ }\ .ace_editor.ace_multiselect .ace_cursor {\ border-left-width: 1px;\ }\ .ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\ position: absolute;\ z-index: 3;\ }\ .ace_marker-layer .ace_selection {\ position: absolute;\ z-index: 5;\ }\ .ace_marker-layer .ace_bracket {\ position: absolute;\ z-index: 6;\ }\ .ace_marker-layer .ace_active-line {\ position: absolute;\ z-index: 2;\ }\ .ace_marker-layer .ace_selected-word {\ position: absolute;\ z-index: 4;\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ }\ .ace_line .ace_fold {\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ display: inline-block;\ height: 11px;\ margin-top: -2px;\ vertical-align: middle;\ background-image:\ url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\ url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");\ background-repeat: no-repeat, repeat-x;\ background-position: center center, top left;\ color: transparent;\ border: 1px solid black;\ border-radius: 2px;\ cursor: pointer;\ pointer-events: auto;\ }\ .ace_dark .ace_fold {\ }\ .ace_fold:hover{\ background-image:\ url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\ url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");\ }\ .ace_tooltip {\ background-color: #FFF;\ background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\ background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\ border: 1px solid gray;\ border-radius: 1px;\ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\ color: black;\ max-width: 100%;\ padding: 3px 4px;\ position: fixed;\ z-index: 999999;\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ cursor: default;\ white-space: pre;\ word-wrap: break-word;\ line-height: normal;\ font-style: normal;\ font-weight: normal;\ letter-spacing: normal;\ pointer-events: none;\ }\ .ace_folding-enabled > .ace_gutter-cell {\ padding-right: 13px;\ }\ .ace_fold-widget {\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ margin: 0 -12px 0 1px;\ display: none;\ width: 11px;\ vertical-align: top;\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");\ background-repeat: no-repeat;\ background-position: center;\ border-radius: 3px;\ border: 1px solid transparent;\ cursor: pointer;\ }\ .ace_folding-enabled .ace_fold-widget {\ display: inline-block; \ }\ .ace_fold-widget.ace_end {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");\ }\ .ace_fold-widget.ace_closed {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");\ }\ .ace_fold-widget:hover {\ border: 1px solid rgba(0, 0, 0, 0.3);\ background-color: rgba(255, 255, 255, 0.2);\ box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\ }\ .ace_fold-widget:active {\ border: 1px solid rgba(0, 0, 0, 0.4);\ background-color: rgba(0, 0, 0, 0.05);\ box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\ }\ .ace_dark .ace_fold-widget {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\ }\ .ace_dark .ace_fold-widget.ace_end {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\ }\ .ace_dark .ace_fold-widget.ace_closed {\ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\ }\ .ace_dark .ace_fold-widget:hover {\ box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\ background-color: rgba(255, 255, 255, 0.1);\ }\ .ace_dark .ace_fold-widget:active {\ box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\ }\ .ace_fold-widget.ace_invalid {\ background-color: #FFB4B4;\ border-color: #DE5555;\ }\ .ace_fade-fold-widgets .ace_fold-widget {\ -webkit-transition: opacity 0.4s ease 0.05s;\ transition: opacity 0.4s ease 0.05s;\ opacity: 0;\ }\ .ace_fade-fold-widgets:hover .ace_fold-widget {\ -webkit-transition: opacity 0.05s ease 0.05s;\ transition: opacity 0.05s ease 0.05s;\ opacity:1;\ }\ .ace_underline {\ text-decoration: underline;\ }\ .ace_bold {\ font-weight: bold;\ }\ .ace_nobold .ace_bold {\ font-weight: normal;\ }\ .ace_italic {\ font-style: italic;\ }\ .ace_error-marker {\ background-color: rgba(255, 0, 0,0.2);\ position: absolute;\ z-index: 9;\ }\ .ace_highlight-marker {\ background-color: rgba(255, 255, 0,0.2);\ position: absolute;\ z-index: 8;\ }\ "; dom.importCssString(editorCss, "ace_editor"); var VirtualRenderer = function(container, theme) { var _self = this; this.container = container || dom.createElement("div"); this.$keepTextAreaAtCursor = !useragent.isOldIE; dom.addCssClass(this.container, "ace_editor"); this.setTheme(theme); this.$gutter = dom.createElement("div"); this.$gutter.className = "ace_gutter"; this.container.appendChild(this.$gutter); this.scroller = dom.createElement("div"); this.scroller.className = "ace_scroller"; this.container.appendChild(this.scroller); this.content = dom.createElement("div"); this.content.className = "ace_content"; this.scroller.appendChild(this.content); this.$gutterLayer = new GutterLayer(this.$gutter); this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this)); this.$markerBack = new MarkerLayer(this.content); var textLayer = this.$textLayer = new TextLayer(this.content); this.canvas = textLayer.element; this.$markerFront = new MarkerLayer(this.content); this.$cursorLayer = new CursorLayer(this.content); this.$horizScroll = false; this.$vScroll = false; this.scrollBar = this.scrollBarV = new VScrollBar(this.container, this); this.scrollBarH = new HScrollBar(this.container, this); this.scrollBarV.addEventListener("scroll", function(e) { if (!_self.$scrollAnimation) _self.session.setScrollTop(e.data - _self.scrollMargin.top); }); this.scrollBarH.addEventListener("scroll", function(e) { if (!_self.$scrollAnimation) _self.session.setScrollLeft(e.data - _self.scrollMargin.left); }); this.scrollTop = 0; this.scrollLeft = 0; this.cursorPos = { row : 0, column : 0 }; this.$fontMetrics = new FontMetrics(this.container, 500); this.$textLayer.$setFontMetrics(this.$fontMetrics); this.$textLayer.addEventListener("changeCharacterSize", function(e) { _self.updateCharacterSize(); _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height); _self._signal("changeCharacterSize", e); }); this.$size = { width: 0, height: 0, scrollerHeight: 0, scrollerWidth: 0, $dirty: true }; this.layerConfig = { width : 1, padding : 0, firstRow : 0, firstRowScreen: 0, lastRow : 0, lineHeight : 0, characterWidth : 0, minHeight : 1, maxHeight : 1, offset : 0, height : 1, gutterOffset: 1 }; this.scrollMargin = { left: 0, right: 0, top: 0, bottom: 0, v: 0, h: 0 }; this.$loop = new RenderLoop( this.$renderChanges.bind(this), this.container.ownerDocument.defaultView ); this.$loop.schedule(this.CHANGE_FULL); this.updateCharacterSize(); this.setPadding(4); config.resetOptions(this); config._emit("renderer", this); }; (function() { this.CHANGE_CURSOR = 1; this.CHANGE_MARKER = 2; this.CHANGE_GUTTER = 4; this.CHANGE_SCROLL = 8; this.CHANGE_LINES = 16; this.CHANGE_TEXT = 32; this.CHANGE_SIZE = 64; this.CHANGE_MARKER_BACK = 128; this.CHANGE_MARKER_FRONT = 256; this.CHANGE_FULL = 512; this.CHANGE_H_SCROLL = 1024; oop.implement(this, EventEmitter); this.updateCharacterSize = function() { if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) { this.$allowBoldFonts = this.$textLayer.allowBoldFonts; this.setStyle("ace_nobold", !this.$allowBoldFonts); } this.layerConfig.characterWidth = this.characterWidth = this.$textLayer.getCharacterWidth(); this.layerConfig.lineHeight = this.lineHeight = this.$textLayer.getLineHeight(); this.$updatePrintMargin(); }; this.setSession = function(session) { if (this.session) this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode); this.session = session; if (session && this.scrollMargin.top && session.getScrollTop() <= 0) session.setScrollTop(-this.scrollMargin.top); this.$cursorLayer.setSession(session); this.$markerBack.setSession(session); this.$markerFront.setSession(session); this.$gutterLayer.setSession(session); this.$textLayer.setSession(session); if (!session) return; this.$loop.schedule(this.CHANGE_FULL); this.session.$setFontMetrics(this.$fontMetrics); this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this); this.onChangeNewLineMode() this.session.doc.on("changeNewLineMode", this.onChangeNewLineMode); }; this.updateLines = function(firstRow, lastRow, force) { if (lastRow === undefined) lastRow = Infinity; if (!this.$changedLines) { this.$changedLines = { firstRow: firstRow, lastRow: lastRow }; } else { if (this.$changedLines.firstRow > firstRow) this.$changedLines.firstRow = firstRow; if (this.$changedLines.lastRow < lastRow) this.$changedLines.lastRow = lastRow; } if (this.$changedLines.lastRow < this.layerConfig.firstRow) { if (force) this.$changedLines.lastRow = this.layerConfig.lastRow; else return; } if (this.$changedLines.firstRow > this.layerConfig.lastRow) return; this.$loop.schedule(this.CHANGE_LINES); }; this.onChangeNewLineMode = function() { this.$loop.schedule(this.CHANGE_TEXT); this.$textLayer.$updateEolChar(); }; this.onChangeTabSize = function() { this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER); this.$textLayer.onChangeTabSize(); }; this.updateText = function() { this.$loop.schedule(this.CHANGE_TEXT); }; this.updateFull = function(force) { if (force) this.$renderChanges(this.CHANGE_FULL, true); else this.$loop.schedule(this.CHANGE_FULL); }; this.updateFontSize = function() { this.$textLayer.checkForSizeChanges(); }; this.$changes = 0; this.$updateSizeAsync = function() { if (this.$loop.pending) this.$size.$dirty = true; else this.onResize(); }; this.onResize = function(force, gutterWidth, width, height) { if (this.resizing > 2) return; else if (this.resizing > 0) this.resizing++; else this.resizing = force ? 1 : 0; var el = this.container; if (!height) height = el.clientHeight || el.scrollHeight; if (!width) width = el.clientWidth || el.scrollWidth; var changes = this.$updateCachedSize(force, gutterWidth, width, height); if (!this.$size.scrollerHeight || (!width && !height)) return this.resizing = 0; if (force) this.$gutterLayer.$padding = null; if (force) this.$renderChanges(changes | this.$changes, true); else this.$loop.schedule(changes | this.$changes); if (this.resizing) this.resizing = 0; }; this.$updateCachedSize = function(force, gutterWidth, width, height) { height -= (this.$extraHeight || 0); var changes = 0; var size = this.$size; var oldSize = { width: size.width, height: size.height, scrollerHeight: size.scrollerHeight, scrollerWidth: size.scrollerWidth }; if (height && (force || size.height != height)) { size.height = height; changes |= this.CHANGE_SIZE; size.scrollerHeight = size.height; if (this.$horizScroll) size.scrollerHeight -= this.scrollBarH.getHeight(); this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px"; changes = changes | this.CHANGE_SCROLL; } if (width && (force || size.width != width)) { changes |= this.CHANGE_SIZE; size.width = width; if (gutterWidth == null) gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0; this.gutterWidth = gutterWidth; this.scrollBarH.element.style.left = this.scroller.style.left = gutterWidth + "px"; size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth()); this.scrollBarH.element.style.right = this.scroller.style.right = this.scrollBarV.getWidth() + "px"; this.scroller.style.bottom = this.scrollBarH.getHeight() + "px"; if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force) changes |= this.CHANGE_FULL; } size.$dirty = !width || !height; if (changes) this._signal("resize", oldSize); return changes; }; this.onGutterResize = function() { var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0; if (gutterWidth != this.gutterWidth) this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height); if (this.session.getUseWrapMode() && this.adjustWrapLimit()) { this.$loop.schedule(this.CHANGE_FULL); } else if (this.$size.$dirty) { this.$loop.schedule(this.CHANGE_FULL); } else { this.$computeLayerConfig(); this.$loop.schedule(this.CHANGE_MARKER); } }; this.adjustWrapLimit = function() { var availableWidth = this.$size.scrollerWidth - this.$padding * 2; var limit = Math.floor(availableWidth / this.characterWidth); return this.session.adjustWrapLimit(limit, this.$showPrintMargin && this.$printMarginColumn); }; this.setAnimatedScroll = function(shouldAnimate){ this.setOption("animatedScroll", shouldAnimate); }; this.getAnimatedScroll = function() { return this.$animatedScroll; }; this.setShowInvisibles = function(showInvisibles) { this.setOption("showInvisibles", showInvisibles); }; this.getShowInvisibles = function() { return this.getOption("showInvisibles"); }; this.getDisplayIndentGuides = function() { return this.getOption("displayIndentGuides"); }; this.setDisplayIndentGuides = function(display) { this.setOption("displayIndentGuides", display); }; this.setShowPrintMargin = function(showPrintMargin) { this.setOption("showPrintMargin", showPrintMargin); }; this.getShowPrintMargin = function() { return this.getOption("showPrintMargin"); }; this.setPrintMarginColumn = function(showPrintMargin) { this.setOption("printMarginColumn", showPrintMargin); }; this.getPrintMarginColumn = function() { return this.getOption("printMarginColumn"); }; this.getShowGutter = function(){ return this.getOption("showGutter"); }; this.setShowGutter = function(show){ return this.setOption("showGutter", show); }; this.getFadeFoldWidgets = function(){ return this.getOption("fadeFoldWidgets") }; this.setFadeFoldWidgets = function(show) { this.setOption("fadeFoldWidgets", show); }; this.setHighlightGutterLine = function(shouldHighlight) { this.setOption("highlightGutterLine", shouldHighlight); }; this.getHighlightGutterLine = function() { return this.getOption("highlightGutterLine"); }; this.$updateGutterLineHighlight = function() { var pos = this.$cursorLayer.$pixelPos; var height = this.layerConfig.lineHeight; if (this.session.getUseWrapMode()) { var cursor = this.session.selection.getCursor(); cursor.column = 0; pos = this.$cursorLayer.getPixelPosition(cursor, true); height *= this.session.getRowLength(cursor.row); } this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px"; this.$gutterLineHighlight.style.height = height + "px"; }; this.$updatePrintMargin = function() { if (!this.$showPrintMargin && !this.$printMarginEl) return; if (!this.$printMarginEl) { var containerEl = dom.createElement("div"); containerEl.className = "ace_layer ace_print-margin-layer"; this.$printMarginEl = dom.createElement("div"); this.$printMarginEl.className = "ace_print-margin"; containerEl.appendChild(this.$printMarginEl); this.content.insertBefore(containerEl, this.content.firstChild); } var style = this.$printMarginEl.style; style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding) + "px"; style.visibility = this.$showPrintMargin ? "visible" : "hidden"; if (this.session && this.session.$wrap == -1) this.adjustWrapLimit(); }; this.getContainerElement = function() { return this.container; }; this.getMouseEventTarget = function() { return this.content; }; this.getTextAreaContainer = function() { return this.container; }; this.$moveTextAreaToCursor = function() { if (!this.$keepTextAreaAtCursor) return; var config = this.layerConfig; var posTop = this.$cursorLayer.$pixelPos.top; var posLeft = this.$cursorLayer.$pixelPos.left; posTop -= config.offset; var h = this.lineHeight; if (posTop < 0 || posTop > config.height - h) return; var w = this.characterWidth; if (this.$composition) { var val = this.textarea.value.replace(/^\x01+/, ""); w *= (this.session.$getStringScreenWidth(val)[0]+2); h += 2; } posLeft -= this.scrollLeft; if (posLeft > this.$size.scrollerWidth - w) posLeft = this.$size.scrollerWidth - w; posLeft += this.gutterWidth; this.textarea.style.height = h + "px"; this.textarea.style.width = w + "px"; this.textarea.style.left = Math.min(posLeft, this.$size.scrollerWidth - w) + "px"; this.textarea.style.top = Math.min(posTop, this.$size.height - h) + "px"; }; this.getFirstVisibleRow = function() { return this.layerConfig.firstRow; }; this.getFirstFullyVisibleRow = function() { return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1); }; this.getLastFullyVisibleRow = function() { var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight); return this.layerConfig.firstRow - 1 + flint; }; this.getLastVisibleRow = function() { return this.layerConfig.lastRow; }; this.$padding = null; this.setPadding = function(padding) { this.$padding = padding; this.$textLayer.setPadding(padding); this.$cursorLayer.setPadding(padding); this.$markerFront.setPadding(padding); this.$markerBack.setPadding(padding); this.$loop.schedule(this.CHANGE_FULL); this.$updatePrintMargin(); }; this.setScrollMargin = function(top, bottom, left, right) { var sm = this.scrollMargin; sm.top = top|0; sm.bottom = bottom|0; sm.right = right|0; sm.left = left|0; sm.v = sm.top + sm.bottom; sm.h = sm.left + sm.right; if (sm.top && this.scrollTop <= 0 && this.session) this.session.setScrollTop(-sm.top); this.updateFull(); }; this.getHScrollBarAlwaysVisible = function() { return this.$hScrollBarAlwaysVisible; }; this.setHScrollBarAlwaysVisible = function(alwaysVisible) { this.setOption("hScrollBarAlwaysVisible", alwaysVisible); }; this.getVScrollBarAlwaysVisible = function() { return this.$hScrollBarAlwaysVisible; }; this.setVScrollBarAlwaysVisible = function(alwaysVisible) { this.setOption("vScrollBarAlwaysVisible", alwaysVisible); }; this.$updateScrollBarV = function() { var scrollHeight = this.layerConfig.maxHeight; var scrollerHeight = this.$size.scrollerHeight; if (!this.$maxLines && this.$scrollPastEnd) { scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd; if (this.scrollTop > scrollHeight - scrollerHeight) { scrollHeight = this.scrollTop + scrollerHeight; this.scrollBarV.scrollTop = null; } } this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v); this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top); }; this.$updateScrollBarH = function() { this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h); this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left); }; this.$frozen = false; this.freeze = function() { this.$frozen = true; }; this.unfreeze = function() { this.$frozen = false; }; this.$renderChanges = function(changes, force) { if (this.$changes) { changes |= this.$changes; this.$changes = 0; } if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) { this.$changes |= changes; return; } if (this.$size.$dirty) { this.$changes |= changes; return this.onResize(true); } if (!this.lineHeight) { this.$textLayer.checkForSizeChanges(); } this._signal("beforeRender"); var config = this.layerConfig; if (changes & this.CHANGE_FULL || changes & this.CHANGE_SIZE || changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES || changes & this.CHANGE_SCROLL || changes & this.CHANGE_H_SCROLL ) { changes |= this.$computeLayerConfig(); if (config.firstRow != this.layerConfig.firstRow && config.firstRowScreen == this.layerConfig.firstRowScreen) { var st = this.scrollTop + (config.firstRow - this.layerConfig.firstRow) * this.lineHeight; if (st > 0) { this.scrollTop = st; changes = changes | this.CHANGE_SCROLL; changes |= this.$computeLayerConfig(); } } config = this.layerConfig; this.$updateScrollBarV(); if (changes & this.CHANGE_H_SCROLL) this.$updateScrollBarH(); this.$gutterLayer.element.style.marginTop = (-config.offset) + "px"; this.content.style.marginTop = (-config.offset) + "px"; this.content.style.width = config.width + 2 * this.$padding + "px"; this.content.style.height = config.minHeight + "px"; } if (changes & this.CHANGE_H_SCROLL) { this.content.style.marginLeft = -this.scrollLeft + "px"; this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left"; } if (changes & this.CHANGE_FULL) { this.$textLayer.update(config); if (this.$showGutter) this.$gutterLayer.update(config); this.$markerBack.update(config); this.$markerFront.update(config); this.$cursorLayer.update(config); this.$moveTextAreaToCursor(); this.$highlightGutterLine && this.$updateGutterLineHighlight(); this._signal("afterRender"); return; } if (changes & this.CHANGE_SCROLL) { if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) this.$textLayer.update(config); else this.$textLayer.scrollLines(config); if (this.$showGutter) this.$gutterLayer.update(config); this.$markerBack.update(config); this.$markerFront.update(config); this.$cursorLayer.update(config); this.$highlightGutterLine && this.$updateGutterLineHighlight(); this.$moveTextAreaToCursor(); this._signal("afterRender"); return; } if (changes & this.CHANGE_TEXT) { this.$textLayer.update(config); if (this.$showGutter) this.$gutterLayer.update(config); } else if (changes & this.CHANGE_LINES) { if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter) this.$gutterLayer.update(config); } else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) { if (this.$showGutter) this.$gutterLayer.update(config); } if (changes & this.CHANGE_CURSOR) { this.$cursorLayer.update(config); this.$moveTextAreaToCursor(); this.$highlightGutterLine && this.$updateGutterLineHighlight(); } if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) { this.$markerFront.update(config); } if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) { this.$markerBack.update(config); } this._signal("afterRender"); }; this.$autosize = function() { var height = this.session.getScreenLength() * this.lineHeight; var maxHeight = this.$maxLines * this.lineHeight; var desiredHeight = Math.max( (this.$minLines||1) * this.lineHeight, Math.min(maxHeight, height) ) + this.scrollMargin.v + (this.$extraHeight || 0); var vScroll = height > maxHeight; if (desiredHeight != this.desiredHeight || this.$size.height != this.desiredHeight || vScroll != this.$vScroll) { if (vScroll != this.$vScroll) { this.$vScroll = vScroll; this.scrollBarV.setVisible(vScroll); } var w = this.container.clientWidth; this.container.style.height = desiredHeight + "px"; this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight); this.desiredHeight = desiredHeight; this._signal("autosize"); } }; this.$computeLayerConfig = function() { if (this.$maxLines && this.lineHeight > 1) this.$autosize(); var session = this.session; var size = this.$size; var hideScrollbars = size.height <= 2 * this.lineHeight; var screenLines = this.session.getScreenLength(); var maxHeight = screenLines * this.lineHeight; var offset = this.scrollTop % this.lineHeight; var minHeight = size.scrollerHeight + this.lineHeight; var longestLine = this.$getLongestLine(); var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible || size.scrollerWidth - longestLine - 2 * this.$padding < 0); var hScrollChanged = this.$horizScroll !== horizScroll; if (hScrollChanged) { this.$horizScroll = horizScroll; this.scrollBarH.setVisible(horizScroll); } var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd : 0; maxHeight += scrollPastEnd; this.session.setScrollTop(Math.max(-this.scrollMargin.top, Math.min(this.scrollTop, maxHeight - size.scrollerHeight + this.scrollMargin.bottom))); this.session.setScrollLeft(Math.max(-this.scrollMargin.left, Math.min(this.scrollLeft, longestLine + 2 * this.$padding - size.scrollerWidth + this.scrollMargin.right))); var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible || size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop); var vScrollChanged = this.$vScroll !== vScroll; if (vScrollChanged) { this.$vScroll = vScroll; this.scrollBarV.setVisible(vScroll); } var lineCount = Math.ceil(minHeight / this.lineHeight) - 1; var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight)); var lastRow = firstRow + lineCount; var firstRowScreen, firstRowHeight; var lineHeight = this.lineHeight; firstRow = session.screenToDocumentRow(firstRow, 0); var foldLine = session.getFoldLine(firstRow); if (foldLine) { firstRow = foldLine.start.row; } firstRowScreen = session.documentToScreenRow(firstRow, 0); firstRowHeight = session.getRowLength(firstRow) * lineHeight; lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1); minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight + firstRowHeight; offset = this.scrollTop - firstRowScreen * lineHeight; var changes = 0; if (this.layerConfig.width != longestLine) changes = this.CHANGE_H_SCROLL; if (hScrollChanged || vScrollChanged) { changes = this.$updateCachedSize(true, this.gutterWidth, size.width, size.height); this._signal("scrollbarVisibilityChanged"); if (vScrollChanged) longestLine = this.$getLongestLine(); } this.layerConfig = { width : longestLine, padding : this.$padding, firstRow : firstRow, firstRowScreen: firstRowScreen, lastRow : lastRow, lineHeight : lineHeight, characterWidth : this.characterWidth, minHeight : minHeight, maxHeight : maxHeight, offset : offset, gutterOffset : Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)), height : this.$size.scrollerHeight }; return changes; }; this.$updateLines = function() { var firstRow = this.$changedLines.firstRow; var lastRow = this.$changedLines.lastRow; this.$changedLines = null; var layerConfig = this.layerConfig; if (firstRow > layerConfig.lastRow + 1) { return; } if (lastRow < layerConfig.firstRow) { return; } if (lastRow === Infinity) { if (this.$showGutter) this.$gutterLayer.update(layerConfig); this.$textLayer.update(layerConfig); return; } this.$textLayer.updateLines(layerConfig, firstRow, lastRow); return true; }; this.$getLongestLine = function() { var charCount = this.session.getScreenWidth(); if (this.showInvisibles && !this.session.$useWrapMode) charCount += 1; return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth)); }; this.updateFrontMarkers = function() { this.$markerFront.setMarkers(this.session.getMarkers(true)); this.$loop.schedule(this.CHANGE_MARKER_FRONT); }; this.updateBackMarkers = function() { this.$markerBack.setMarkers(this.session.getMarkers()); this.$loop.schedule(this.CHANGE_MARKER_BACK); }; this.addGutterDecoration = function(row, className){ this.$gutterLayer.addGutterDecoration(row, className); }; this.removeGutterDecoration = function(row, className){ this.$gutterLayer.removeGutterDecoration(row, className); }; this.updateBreakpoints = function(rows) { this.$loop.schedule(this.CHANGE_GUTTER); }; this.setAnnotations = function(annotations) { this.$gutterLayer.setAnnotations(annotations); this.$loop.schedule(this.CHANGE_GUTTER); }; this.updateCursor = function() { this.$loop.schedule(this.CHANGE_CURSOR); }; this.hideCursor = function() { this.$cursorLayer.hideCursor(); }; this.showCursor = function() { this.$cursorLayer.showCursor(); }; this.scrollSelectionIntoView = function(anchor, lead, offset) { this.scrollCursorIntoView(anchor, offset); this.scrollCursorIntoView(lead, offset); }; this.scrollCursorIntoView = function(cursor, offset, $viewMargin) { if (this.$size.scrollerHeight === 0) return; var pos = this.$cursorLayer.getPixelPosition(cursor); var left = pos.left; var top = pos.top; var topMargin = $viewMargin && $viewMargin.top || 0; var bottomMargin = $viewMargin && $viewMargin.bottom || 0; var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop; if (scrollTop + topMargin > top) { if (offset) top -= offset * this.$size.scrollerHeight; if (top === 0) top = -this.scrollMargin.top; this.session.setScrollTop(top); } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) { if (offset) top += offset * this.$size.scrollerHeight; this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight); } var scrollLeft = this.scrollLeft; if (scrollLeft > left) { if (left < this.$padding + 2 * this.layerConfig.characterWidth) left = -this.scrollMargin.left; this.session.setScrollLeft(left); } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) { this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth)); } else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) { this.session.setScrollLeft(0); } }; this.getScrollTop = function() { return this.session.getScrollTop(); }; this.getScrollLeft = function() { return this.session.getScrollLeft(); }; this.getScrollTopRow = function() { return this.scrollTop / this.lineHeight; }; this.getScrollBottomRow = function() { return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1); }; this.scrollToRow = function(row) { this.session.setScrollTop(row * this.lineHeight); }; this.alignCursor = function(cursor, alignment) { if (typeof cursor == "number") cursor = {row: cursor, column: 0}; var pos = this.$cursorLayer.getPixelPosition(cursor); var h = this.$size.scrollerHeight - this.lineHeight; var offset = pos.top - h * (alignment || 0); this.session.setScrollTop(offset); return offset; }; this.STEPS = 8; this.$calcSteps = function(fromValue, toValue){ var i = 0; var l = this.STEPS; var steps = []; var func = function(t, x_min, dx) { return dx * (Math.pow(t - 1, 3) + 1) + x_min; }; for (i = 0; i < l; ++i) steps.push(func(i / this.STEPS, fromValue, toValue - fromValue)); return steps; }; this.scrollToLine = function(line, center, animate, callback) { var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0}); var offset = pos.top; if (center) offset -= this.$size.scrollerHeight / 2; var initialScroll = this.scrollTop; this.session.setScrollTop(offset); if (animate !== false) this.animateScrolling(initialScroll, callback); }; this.animateScrolling = function(fromValue, callback) { var toValue = this.scrollTop; if (!this.$animatedScroll) return; var _self = this; if (fromValue == toValue) return; if (this.$scrollAnimation) { var oldSteps = this.$scrollAnimation.steps; if (oldSteps.length) { fromValue = oldSteps[0]; if (fromValue == toValue) return; } } var steps = _self.$calcSteps(fromValue, toValue); this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps}; clearInterval(this.$timer); _self.session.setScrollTop(steps.shift()); _self.session.$scrollTop = toValue; this.$timer = setInterval(function() { if (steps.length) { _self.session.setScrollTop(steps.shift()); _self.session.$scrollTop = toValue; } else if (toValue != null) { _self.session.$scrollTop = -1; _self.session.setScrollTop(toValue); toValue = null; } else { _self.$timer = clearInterval(_self.$timer); _self.$scrollAnimation = null; callback && callback(); } }, 10); }; this.scrollToY = function(scrollTop) { if (this.scrollTop !== scrollTop) { this.$loop.schedule(this.CHANGE_SCROLL); this.scrollTop = scrollTop; } }; this.scrollToX = function(scrollLeft) { if (this.scrollLeft !== scrollLeft) this.scrollLeft = scrollLeft; this.$loop.schedule(this.CHANGE_H_SCROLL); }; this.scrollTo = function(x, y) { this.session.setScrollTop(y); this.session.setScrollLeft(y); }; this.scrollBy = function(deltaX, deltaY) { deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY); deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX); }; this.isScrollableBy = function(deltaX, deltaY) { if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top) return true; if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom) return true; if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left) return true; if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth - this.layerConfig.width < -1 + this.scrollMargin.right) return true; }; this.pixelToScreenCoordinates = function(x, y) { var canvasPos = this.scroller.getBoundingClientRect(); var offset = (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth; var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight); var col = Math.round(offset); return {row: row, column: col, side: offset - col > 0 ? 1 : -1}; }; this.screenToTextCoordinates = function(x, y) { var canvasPos = this.scroller.getBoundingClientRect(); var col = Math.round( (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth ); var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight; return this.session.screenToDocumentPosition(row, Math.max(col, 0)); }; this.textToScreenCoordinates = function(row, column) { var canvasPos = this.scroller.getBoundingClientRect(); var pos = this.session.documentToScreenPosition(row, column); var x = this.$padding + Math.round(pos.column * this.characterWidth); var y = pos.row * this.lineHeight; return { pageX: canvasPos.left + x - this.scrollLeft, pageY: canvasPos.top + y - this.scrollTop }; }; this.visualizeFocus = function() { dom.addCssClass(this.container, "ace_focus"); }; this.visualizeBlur = function() { dom.removeCssClass(this.container, "ace_focus"); }; this.showComposition = function(position) { if (!this.$composition) this.$composition = { keepTextAreaAtCursor: this.$keepTextAreaAtCursor, cssText: this.textarea.style.cssText }; this.$keepTextAreaAtCursor = true; dom.addCssClass(this.textarea, "ace_composition"); this.textarea.style.cssText = ""; this.$moveTextAreaToCursor(); }; this.setCompositionText = function(text) { this.$moveTextAreaToCursor(); }; this.hideComposition = function() { if (!this.$composition) return; dom.removeCssClass(this.textarea, "ace_composition"); this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor; this.textarea.style.cssText = this.$composition.cssText; this.$composition = null; }; this.setTheme = function(theme, cb) { var _self = this; this.$themeId = theme; _self._dispatchEvent('themeChange',{theme:theme}); if (!theme || typeof theme == "string") { var moduleName = theme || this.$options.theme.initialValue; config.loadModule(["theme", moduleName], afterLoad); } else { afterLoad(theme); } function afterLoad(module) { if (_self.$themeId != theme) return cb && cb(); if (!module.cssClass) return; dom.importCssString( module.cssText, module.cssClass, _self.container.ownerDocument ); if (_self.theme) dom.removeCssClass(_self.container, _self.theme.cssClass); var padding = "padding" in module ? module.padding : "padding" in (_self.theme || {}) ? 4 : _self.$padding; if (_self.$padding && padding != _self.$padding) _self.setPadding(padding); _self.$theme = module.cssClass; _self.theme = module; dom.addCssClass(_self.container, module.cssClass); dom.setCssClass(_self.container, "ace_dark", module.isDark); if (_self.$size) { _self.$size.width = 0; _self.$updateSizeAsync(); } _self._dispatchEvent('themeLoaded', {theme:module}); cb && cb(); } }; this.getTheme = function() { return this.$themeId; }; this.setStyle = function(style, include) { dom.setCssClass(this.container, style, include !== false); }; this.unsetStyle = function(style) { dom.removeCssClass(this.container, style); }; this.setCursorStyle = function(style) { if (this.scroller.style.cursor != style) this.scroller.style.cursor = style; }; this.setMouseCursor = function(cursorStyle) { this.scroller.style.cursor = cursorStyle; }; this.destroy = function() { this.$textLayer.destroy(); this.$cursorLayer.destroy(); }; }).call(VirtualRenderer.prototype); config.defineOptions(VirtualRenderer.prototype, "renderer", { animatedScroll: {initialValue: false}, showInvisibles: { set: function(value) { if (this.$textLayer.setShowInvisibles(value)) this.$loop.schedule(this.CHANGE_TEXT); }, initialValue: false }, showPrintMargin: { set: function() { this.$updatePrintMargin(); }, initialValue: true }, printMarginColumn: { set: function() { this.$updatePrintMargin(); }, initialValue: 80 }, printMargin: { set: function(val) { if (typeof val == "number") this.$printMarginColumn = val; this.$showPrintMargin = !!val; this.$updatePrintMargin(); }, get: function() { return this.$showPrintMargin && this.$printMarginColumn; } }, showGutter: { set: function(show){ this.$gutter.style.display = show ? "block" : "none"; this.$loop.schedule(this.CHANGE_FULL); this.onGutterResize(); }, initialValue: true }, fadeFoldWidgets: { set: function(show) { dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show); }, initialValue: false }, showFoldWidgets: { set: function(show) {this.$gutterLayer.setShowFoldWidgets(show)}, initialValue: true }, showLineNumbers: { set: function(show) { this.$gutterLayer.setShowLineNumbers(show); this.$loop.schedule(this.CHANGE_GUTTER); }, initialValue: true }, displayIndentGuides: { set: function(show) { if (this.$textLayer.setDisplayIndentGuides(show)) this.$loop.schedule(this.CHANGE_TEXT); }, initialValue: true }, highlightGutterLine: { set: function(shouldHighlight) { if (!this.$gutterLineHighlight) { this.$gutterLineHighlight = dom.createElement("div"); this.$gutterLineHighlight.className = "ace_gutter-active-line"; this.$gutter.appendChild(this.$gutterLineHighlight); return; } this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none"; if (this.$cursorLayer.$pixelPos) this.$updateGutterLineHighlight(); }, initialValue: false, value: true }, hScrollBarAlwaysVisible: { set: function(val) { if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll) this.$loop.schedule(this.CHANGE_SCROLL); }, initialValue: false }, vScrollBarAlwaysVisible: { set: function(val) { if (!this.$vScrollBarAlwaysVisible || !this.$vScroll) this.$loop.schedule(this.CHANGE_SCROLL); }, initialValue: false }, fontSize: { set: function(size) { if (typeof size == "number") size = size + "px"; this.container.style.fontSize = size; this.updateFontSize(); }, initialValue: 12 }, fontFamily: { set: function(name) { this.container.style.fontFamily = name; this.updateFontSize(); } }, maxLines: { set: function(val) { this.updateFull(); } }, minLines: { set: function(val) { this.updateFull(); } }, scrollPastEnd: { set: function(val) { val = +val || 0; if (this.$scrollPastEnd == val) return; this.$scrollPastEnd = val; this.$loop.schedule(this.CHANGE_SCROLL); }, initialValue: 0, handlesSet: true }, fixedWidthGutter: { set: function(val) { this.$gutterLayer.$fixedWidth = !!val; this.$loop.schedule(this.CHANGE_GUTTER); } }, theme: { set: function(val) { this.setTheme(val) }, get: function() { return this.$themeId || this.theme; }, initialValue: "./theme/textmate", handlesSet: true } }); exports.VirtualRenderer = VirtualRenderer; }); ace.define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var net = require("../lib/net"); var EventEmitter = require("../lib/event_emitter").EventEmitter; var config = require("../config"); var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl) { this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this); this.changeListener = this.changeListener.bind(this); this.onMessage = this.onMessage.bind(this); if (require.nameToUrl && !require.toUrl) require.toUrl = require.nameToUrl; if (config.get("packaged") || !require.toUrl) { workerUrl = workerUrl || config.moduleUrl(mod, "worker"); } else { var normalizePath = this.$normalizePath; workerUrl = workerUrl || normalizePath(require.toUrl("ace/worker/worker.js", null, "_")); var tlns = {}; topLevelNamespaces.forEach(function(ns) { tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, "")); }); } try { this.$worker = new Worker(workerUrl); } catch(e) { if (e instanceof window.DOMException) { var blob = this.$workerBlob(workerUrl); var URL = window.URL || window.webkitURL; var blobURL = URL.createObjectURL(blob); this.$worker = new Worker(blobURL); URL.revokeObjectURL(blobURL); } else { throw e; } } this.$worker.postMessage({ init : true, tlns : tlns, module : mod, classname : classname }); this.callbackId = 1; this.callbacks = {}; this.$worker.onmessage = this.onMessage; }; (function(){ oop.implement(this, EventEmitter); this.onMessage = function(e) { var msg = e.data; switch(msg.type) { case "event": this._signal(msg.name, {data: msg.data}); break; case "call": var callback = this.callbacks[msg.id]; if (callback) { callback(msg.data); delete this.callbacks[msg.id]; } break; case "error": this.reportError(msg.data); break; case "log": window.console && console.log && console.log.apply(console, msg.data); break; } }; this.reportError = function(err) { window.console && console.error && console.error(err); }; this.$normalizePath = function(path) { return net.qualifyURL(path); }; this.terminate = function() { this._signal("terminate", {}); this.deltaQueue = null; this.$worker.terminate(); this.$worker = null; if (this.$doc) this.$doc.off("change", this.changeListener); this.$doc = null; }; this.send = function(cmd, args) { this.$worker.postMessage({command: cmd, args: args}); }; this.call = function(cmd, args, callback) { if (callback) { var id = this.callbackId++; this.callbacks[id] = callback; args.push(id); } this.send(cmd, args); }; this.emit = function(event, data) { try { this.$worker.postMessage({event: event, data: {data: data.data}}); } catch(ex) { console.error(ex.stack); } }; this.attachToDocument = function(doc) { if(this.$doc) this.terminate(); this.$doc = doc; this.call("setValue", [doc.getValue()]); doc.on("change", this.changeListener); }; this.changeListener = function(e) { if (!this.deltaQueue) { this.deltaQueue = [e.data]; setTimeout(this.$sendDeltaQueue, 0); } else this.deltaQueue.push(e.data); }; this.$sendDeltaQueue = function() { var q = this.deltaQueue; if (!q) return; this.deltaQueue = null; if (q.length > 20 && q.length > this.$doc.getLength() >> 1) { this.call("setValue", [this.$doc.getValue()]); } else this.emit("change", {data: q}); }; this.$workerBlob = function(workerUrl) { var script = "importScripts('" + net.qualifyURL(workerUrl) + "');"; try { return new Blob([script], {"type": "application/javascript"}); } catch (e) { // Backwards-compatibility var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; var blobBuilder = new BlobBuilder(); blobBuilder.append(script); return blobBuilder.getBlob("application/javascript"); } }; }).call(WorkerClient.prototype); var UIWorkerClient = function(topLevelNamespaces, mod, classname) { this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this); this.changeListener = this.changeListener.bind(this); this.callbackId = 1; this.callbacks = {}; this.messageBuffer = []; var main = null; var emitSync = false; var sender = Object.create(EventEmitter); var _self = this; this.$worker = {}; this.$worker.terminate = function() {}; this.$worker.postMessage = function(e) { _self.messageBuffer.push(e); if (main) { if (emitSync) setTimeout(processNext); else processNext(); } }; this.setEmitSync = function(val) { emitSync = val }; var processNext = function() { var msg = _self.messageBuffer.shift(); if (msg.command) main[msg.command].apply(main, msg.args); else if (msg.event) sender._signal(msg.event, msg.data); }; sender.postMessage = function(msg) { _self.onMessage({data: msg}); }; sender.callback = function(data, callbackId) { this.postMessage({type: "call", id: callbackId, data: data}); }; sender.emit = function(name, data) { this.postMessage({type: "event", name: name, data: data}); }; config.loadModule(["worker", mod], function(Main) { main = new Main[classname](sender); while (_self.messageBuffer.length) processNext(); }); }; UIWorkerClient.prototype = WorkerClient.prototype; exports.UIWorkerClient = UIWorkerClient; exports.WorkerClient = WorkerClient; }); ace.define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"], function(require, exports, module) { "use strict"; var Range = require("./range").Range; var EventEmitter = require("./lib/event_emitter").EventEmitter; var oop = require("./lib/oop"); var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) { var _self = this; this.length = length; this.session = session; this.doc = session.getDocument(); this.mainClass = mainClass; this.othersClass = othersClass; this.$onUpdate = this.onUpdate.bind(this); this.doc.on("change", this.$onUpdate); this.$others = others; this.$onCursorChange = function() { setTimeout(function() { _self.onCursorChange(); }); }; this.$pos = pos; var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1}; this.$undoStackDepth = undoStack.length; this.setup(); session.selection.on("changeCursor", this.$onCursorChange); }; (function() { oop.implement(this, EventEmitter); this.setup = function() { var _self = this; var doc = this.doc; var session = this.session; var pos = this.$pos; this.selectionBefore = session.selection.toJSON(); if (session.selection.inMultiSelectMode) session.selection.toSingleRange(); this.pos = doc.createAnchor(pos.row, pos.column); this.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false); this.pos.on("change", function(event) { session.removeMarker(_self.markerId); _self.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.mainClass, null, false); }); this.others = []; this.$others.forEach(function(other) { var anchor = doc.createAnchor(other.row, other.column); _self.others.push(anchor); }); session.setUndoSelect(false); }; this.showOtherMarkers = function() { if(this.othersActive) return; var session = this.session; var _self = this; this.othersActive = true; this.others.forEach(function(anchor) { anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false); anchor.on("change", function(event) { session.removeMarker(anchor.markerId); anchor.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.othersClass, null, false); }); }); }; this.hideOtherMarkers = function() { if(!this.othersActive) return; this.othersActive = false; for (var i = 0; i < this.others.length; i++) { this.session.removeMarker(this.others[i].markerId); } }; this.onUpdate = function(event) { var delta = event.data; var range = delta.range; if(range.start.row !== range.end.row) return; if(range.start.row !== this.pos.row) return; if (this.$updating) return; this.$updating = true; var lengthDiff = delta.action === "insertText" ? range.end.column - range.start.column : range.start.column - range.end.column; if(range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1) { var distanceFromStart = range.start.column - this.pos.column; this.length += lengthDiff; if(!this.session.$fromUndo) { if(delta.action === "insertText") { for (var i = this.others.length - 1; i >= 0; i--) { var otherPos = this.others[i]; var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart}; if(otherPos.row === range.start.row && range.start.column < otherPos.column) newPos.column += lengthDiff; this.doc.insert(newPos, delta.text); } } else if(delta.action === "removeText") { for (var i = this.others.length - 1; i >= 0; i--) { var otherPos = this.others[i]; var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart}; if(otherPos.row === range.start.row && range.start.column < otherPos.column) newPos.column += lengthDiff; this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff)); } } if(range.start.column === this.pos.column && delta.action === "insertText") { setTimeout(function() { this.pos.setPosition(this.pos.row, this.pos.column - lengthDiff); for (var i = 0; i < this.others.length; i++) { var other = this.others[i]; var newPos = {row: other.row, column: other.column - lengthDiff}; if(other.row === range.start.row && range.start.column < other.column) newPos.column += lengthDiff; other.setPosition(newPos.row, newPos.column); } }.bind(this), 0); } else if(range.start.column === this.pos.column && delta.action === "removeText") { setTimeout(function() { for (var i = 0; i < this.others.length; i++) { var other = this.others[i]; if(other.row === range.start.row && range.start.column < other.column) { other.setPosition(other.row, other.column - lengthDiff); } } }.bind(this), 0); } } this.pos._emit("change", {value: this.pos}); for (var i = 0; i < this.others.length; i++) { this.others[i]._emit("change", {value: this.others[i]}); } } this.$updating = false; }; this.onCursorChange = function(event) { if (this.$updating || !this.session) return; var pos = this.session.selection.getCursor(); if (pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) { this.showOtherMarkers(); this._emit("cursorEnter", event); } else { this.hideOtherMarkers(); this._emit("cursorLeave", event); } }; this.detach = function() { this.session.removeMarker(this.markerId); this.hideOtherMarkers(); this.doc.removeEventListener("change", this.$onUpdate); this.session.selection.removeEventListener("changeCursor", this.$onCursorChange); this.pos.detach(); for (var i = 0; i < this.others.length; i++) { this.others[i].detach(); } this.session.setUndoSelect(true); this.session = null; }; this.cancel = function() { if(this.$undoStackDepth === -1) throw Error("Canceling placeholders only supported with undo manager attached to session."); var undoManager = this.session.getUndoManager(); var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth; for (var i = 0; i < undosRequired; i++) { undoManager.undo(true); } if (this.selectionBefore) this.session.selection.fromJSON(this.selectionBefore); }; }).call(PlaceHolder.prototype); exports.PlaceHolder = PlaceHolder; }); ace.define("ace/mouse/multi_select_handler",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(require, exports, module) { var event = require("../lib/event"); var useragent = require("../lib/useragent"); function isSamePoint(p1, p2) { return p1.row == p2.row && p1.column == p2.column; } function onMouseDown(e) { var ev = e.domEvent; var alt = ev.altKey; var shift = ev.shiftKey; var ctrl = ev.ctrlKey; var accel = e.getAccelKey(); var button = e.getButton(); if (ctrl && useragent.isMac) button = ev.button; if (e.editor.inMultiSelectMode && button == 2) { e.editor.textInput.onContextMenu(e.domEvent); return; } if (!ctrl && !alt && !accel) { if (button === 0 && e.editor.inMultiSelectMode) e.editor.exitMultiSelectMode(); return; } if (button !== 0) return; var editor = e.editor; var selection = editor.selection; var isMultiSelect = editor.inMultiSelectMode; var pos = e.getDocumentPosition(); var cursor = selection.getCursor(); var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor)); var mouseX = e.x, mouseY = e.y; var onMouseSelection = function(e) { mouseX = e.clientX; mouseY = e.clientY; }; var session = editor.session; var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY); var screenCursor = screenAnchor; var selectionMode; if (editor.$mouseHandler.$enableJumpToDef) { if (ctrl && alt || accel && alt) selectionMode = "add"; else if (alt) selectionMode = "block"; } else { if (accel && !alt) { selectionMode = "add"; if (!isMultiSelect && shift) return; } else if (alt) { selectionMode = "block"; } } if (selectionMode && useragent.isMac && ev.ctrlKey) { editor.$mouseHandler.cancelContextMenu(); } if (selectionMode == "add") { if (!isMultiSelect && inSelection) return; // dragging if (!isMultiSelect) { var range = selection.toOrientedRange(); editor.addSelectionMarker(range); } var oldRange = selection.rangeList.rangeAtPoint(pos); editor.$blockScrolling++; editor.inVirtualSelectionMode = true; if (shift) { oldRange = null; range = selection.ranges[0]; editor.removeSelectionMarker(range); } editor.once("mouseup", function() { var tmpSel = selection.toOrientedRange(); if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor)) selection.substractPoint(tmpSel.cursor); else { if (shift) { selection.substractPoint(range.cursor); } else if (range) { editor.removeSelectionMarker(range); selection.addRange(range); } selection.addRange(tmpSel); } editor.$blockScrolling--; editor.inVirtualSelectionMode = false; }); } else if (selectionMode == "block") { e.stop(); editor.inVirtualSelectionMode = true; var initialRange; var rectSel = []; var blockSelect = function() { var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY); var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column); if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead)) return; screenCursor = newCursor; editor.selection.moveToPosition(cursor); editor.renderer.scrollCursorIntoView(); editor.removeSelectionMarkers(rectSel); rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor); if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty()) rectSel[0] = editor.$mouseHandler.$clickSelection.clone(); rectSel.forEach(editor.addSelectionMarker, editor); editor.updateSelectionMarkers(); }; if (isMultiSelect && !accel) { selection.toSingleRange(); } else if (!isMultiSelect && accel) { initialRange = selection.toOrientedRange(); editor.addSelectionMarker(initialRange); } if (shift) screenAnchor = session.documentToScreenPosition(selection.lead); else selection.moveToPosition(pos); screenCursor = {row: -1, column: -1}; var onMouseSelectionEnd = function(e) { clearInterval(timerId); editor.removeSelectionMarkers(rectSel); if (!rectSel.length) rectSel = [selection.toOrientedRange()]; editor.$blockScrolling++; if (initialRange) { editor.removeSelectionMarker(initialRange); selection.toSingleRange(initialRange); } for (var i = 0; i < rectSel.length; i++) selection.addRange(rectSel[i]); editor.inVirtualSelectionMode = false; editor.$mouseHandler.$clickSelection = null; editor.$blockScrolling--; }; var onSelectionInterval = blockSelect; event.capture(editor.container, onMouseSelection, onMouseSelectionEnd); var timerId = setInterval(function() {onSelectionInterval();}, 20); return e.preventDefault(); } } exports.onMouseDown = onMouseDown; }); ace.define("ace/commands/multi_select_commands",["require","exports","module","ace/keyboard/hash_handler"], function(require, exports, module) { exports.defaultCommands = [{ name: "addCursorAbove", exec: function(editor) { editor.selectMoreLines(-1); }, bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"}, readonly: true }, { name: "addCursorBelow", exec: function(editor) { editor.selectMoreLines(1); }, bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"}, readonly: true }, { name: "addCursorAboveSkipCurrent", exec: function(editor) { editor.selectMoreLines(-1, true); }, bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"}, readonly: true }, { name: "addCursorBelowSkipCurrent", exec: function(editor) { editor.selectMoreLines(1, true); }, bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"}, readonly: true }, { name: "selectMoreBefore", exec: function(editor) { editor.selectMore(-1); }, bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"}, readonly: true }, { name: "selectMoreAfter", exec: function(editor) { editor.selectMore(1); }, bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"}, readonly: true }, { name: "selectNextBefore", exec: function(editor) { editor.selectMore(-1, true); }, bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"}, readonly: true }, { name: "selectNextAfter", exec: function(editor) { editor.selectMore(1, true); }, bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"}, readonly: true }, { name: "splitIntoLines", exec: function(editor) { editor.multiSelect.splitIntoLines(); }, bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"}, readonly: true }, { name: "alignCursors", exec: function(editor) { editor.alignCursors(); }, bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"} }, { name: "findAll", exec: function(editor) { editor.findAll(); }, bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"}, readonly: true }]; exports.multiSelectCommands = [{ name: "singleSelection", bindKey: "esc", exec: function(editor) { editor.exitMultiSelectMode(); }, readonly: true, isAvailable: function(editor) {return editor && editor.inMultiSelectMode} }]; var HashHandler = require("../keyboard/hash_handler").HashHandler; exports.keyboardHandler = new HashHandler(exports.multiSelectCommands); }); ace.define("ace/multi_select",["require","exports","module","ace/range_list","ace/range","ace/selection","ace/mouse/multi_select_handler","ace/lib/event","ace/lib/lang","ace/commands/multi_select_commands","ace/search","ace/edit_session","ace/editor","ace/config"], function(require, exports, module) { var RangeList = require("./range_list").RangeList; var Range = require("./range").Range; var Selection = require("./selection").Selection; var onMouseDown = require("./mouse/multi_select_handler").onMouseDown; var event = require("./lib/event"); var lang = require("./lib/lang"); var commands = require("./commands/multi_select_commands"); exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands); var Search = require("./search").Search; var search = new Search(); function find(session, needle, dir) { search.$options.wrap = true; search.$options.needle = needle; search.$options.backwards = dir == -1; return search.find(session); } var EditSession = require("./edit_session").EditSession; (function() { this.getSelectionMarkers = function() { return this.$selectionMarkers; }; }).call(EditSession.prototype); (function() { this.ranges = null; this.rangeList = null; this.addRange = function(range, $blockChangeEvents) { if (!range) return; if (!this.inMultiSelectMode && this.rangeCount === 0) { var oldRange = this.toOrientedRange(); this.rangeList.add(oldRange); this.rangeList.add(range); if (this.rangeList.ranges.length != 2) { this.rangeList.removeAll(); return $blockChangeEvents || this.fromOrientedRange(range); } this.rangeList.removeAll(); this.rangeList.add(oldRange); this.$onAddRange(oldRange); } if (!range.cursor) range.cursor = range.end; var removed = this.rangeList.add(range); this.$onAddRange(range); if (removed.length) this.$onRemoveRange(removed); if (this.rangeCount > 1 && !this.inMultiSelectMode) { this._signal("multiSelect"); this.inMultiSelectMode = true; this.session.$undoSelect = false; this.rangeList.attach(this.session); } return $blockChangeEvents || this.fromOrientedRange(range); }; this.toSingleRange = function(range) { range = range || this.ranges[0]; var removed = this.rangeList.removeAll(); if (removed.length) this.$onRemoveRange(removed); range && this.fromOrientedRange(range); }; this.substractPoint = function(pos) { var removed = this.rangeList.substractPoint(pos); if (removed) { this.$onRemoveRange(removed); return removed[0]; } }; this.mergeOverlappingRanges = function() { var removed = this.rangeList.merge(); if (removed.length) this.$onRemoveRange(removed); else if(this.ranges[0]) this.fromOrientedRange(this.ranges[0]); }; this.$onAddRange = function(range) { this.rangeCount = this.rangeList.ranges.length; this.ranges.unshift(range); this._signal("addRange", {range: range}); }; this.$onRemoveRange = function(removed) { this.rangeCount = this.rangeList.ranges.length; if (this.rangeCount == 1 && this.inMultiSelectMode) { var lastRange = this.rangeList.ranges.pop(); removed.push(lastRange); this.rangeCount = 0; } for (var i = removed.length; i--; ) { var index = this.ranges.indexOf(removed[i]); this.ranges.splice(index, 1); } this._signal("removeRange", {ranges: removed}); if (this.rangeCount === 0 && this.inMultiSelectMode) { this.inMultiSelectMode = false; this._signal("singleSelect"); this.session.$undoSelect = true; this.rangeList.detach(this.session); } lastRange = lastRange || this.ranges[0]; if (lastRange && !lastRange.isEqual(this.getRange())) this.fromOrientedRange(lastRange); }; this.$initRangeList = function() { if (this.rangeList) return; this.rangeList = new RangeList(); this.ranges = []; this.rangeCount = 0; }; this.getAllRanges = function() { return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()]; }; this.splitIntoLines = function () { if (this.rangeCount > 1) { var ranges = this.rangeList.ranges; var lastRange = ranges[ranges.length - 1]; var range = Range.fromPoints(ranges[0].start, lastRange.end); this.toSingleRange(); this.setSelectionRange(range, lastRange.cursor == lastRange.start); } else { var range = this.getRange(); var isBackwards = this.isBackwards(); var startRow = range.start.row; var endRow = range.end.row; if (startRow == endRow) { if (isBackwards) var start = range.end, end = range.start; else var start = range.start, end = range.end; this.addRange(Range.fromPoints(end, end)); this.addRange(Range.fromPoints(start, start)); return; } var rectSel = []; var r = this.getLineRange(startRow, true); r.start.column = range.start.column; rectSel.push(r); for (var i = startRow + 1; i < endRow; i++) rectSel.push(this.getLineRange(i, true)); r = this.getLineRange(endRow, true); r.end.column = range.end.column; rectSel.push(r); rectSel.forEach(this.addRange, this); } }; this.toggleBlockSelection = function () { if (this.rangeCount > 1) { var ranges = this.rangeList.ranges; var lastRange = ranges[ranges.length - 1]; var range = Range.fromPoints(ranges[0].start, lastRange.end); this.toSingleRange(); this.setSelectionRange(range, lastRange.cursor == lastRange.start); } else { var cursor = this.session.documentToScreenPosition(this.selectionLead); var anchor = this.session.documentToScreenPosition(this.selectionAnchor); var rectSel = this.rectangularRangeBlock(cursor, anchor); rectSel.forEach(this.addRange, this); } }; this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) { var rectSel = []; var xBackwards = screenCursor.column < screenAnchor.column; if (xBackwards) { var startColumn = screenCursor.column; var endColumn = screenAnchor.column; } else { var startColumn = screenAnchor.column; var endColumn = screenCursor.column; } var yBackwards = screenCursor.row < screenAnchor.row; if (yBackwards) { var startRow = screenCursor.row; var endRow = screenAnchor.row; } else { var startRow = screenAnchor.row; var endRow = screenCursor.row; } if (startColumn < 0) startColumn = 0; if (startRow < 0) startRow = 0; if (startRow == endRow) includeEmptyLines = true; for (var row = startRow; row <= endRow; row++) { var range = Range.fromPoints( this.session.screenToDocumentPosition(row, startColumn), this.session.screenToDocumentPosition(row, endColumn) ); if (range.isEmpty()) { if (docEnd && isSamePoint(range.end, docEnd)) break; var docEnd = range.end; } range.cursor = xBackwards ? range.start : range.end; rectSel.push(range); } if (yBackwards) rectSel.reverse(); if (!includeEmptyLines) { var end = rectSel.length - 1; while (rectSel[end].isEmpty() && end > 0) end--; if (end > 0) { var start = 0; while (rectSel[start].isEmpty()) start++; } for (var i = end; i >= start; i--) { if (rectSel[i].isEmpty()) rectSel.splice(i, 1); } } return rectSel; }; }).call(Selection.prototype); var Editor = require("./editor").Editor; (function() { this.updateSelectionMarkers = function() { this.renderer.updateCursor(); this.renderer.updateBackMarkers(); }; this.addSelectionMarker = function(orientedRange) { if (!orientedRange.cursor) orientedRange.cursor = orientedRange.end; var style = this.getSelectionStyle(); orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style); this.session.$selectionMarkers.push(orientedRange); this.session.selectionMarkerCount = this.session.$selectionMarkers.length; return orientedRange; }; this.removeSelectionMarker = function(range) { if (!range.marker) return; this.session.removeMarker(range.marker); var index = this.session.$selectionMarkers.indexOf(range); if (index != -1) this.session.$selectionMarkers.splice(index, 1); this.session.selectionMarkerCount = this.session.$selectionMarkers.length; }; this.removeSelectionMarkers = function(ranges) { var markerList = this.session.$selectionMarkers; for (var i = ranges.length; i--; ) { var range = ranges[i]; if (!range.marker) continue; this.session.removeMarker(range.marker); var index = markerList.indexOf(range); if (index != -1) markerList.splice(index, 1); } this.session.selectionMarkerCount = markerList.length; }; this.$onAddRange = function(e) { this.addSelectionMarker(e.range); this.renderer.updateCursor(); this.renderer.updateBackMarkers(); }; this.$onRemoveRange = function(e) { this.removeSelectionMarkers(e.ranges); this.renderer.updateCursor(); this.renderer.updateBackMarkers(); }; this.$onMultiSelect = function(e) { if (this.inMultiSelectMode) return; this.inMultiSelectMode = true; this.setStyle("ace_multiselect"); this.keyBinding.addKeyboardHandler(commands.keyboardHandler); this.commands.setDefaultHandler("exec", this.$onMultiSelectExec); this.renderer.updateCursor(); this.renderer.updateBackMarkers(); }; this.$onSingleSelect = function(e) { if (this.session.multiSelect.inVirtualMode) return; this.inMultiSelectMode = false; this.unsetStyle("ace_multiselect"); this.keyBinding.removeKeyboardHandler(commands.keyboardHandler); this.commands.removeDefaultHandler("exec", this.$onMultiSelectExec); this.renderer.updateCursor(); this.renderer.updateBackMarkers(); this._emit("changeSelection"); }; this.$onMultiSelectExec = function(e) { var command = e.command; var editor = e.editor; if (!editor.multiSelect) return; if (!command.multiSelectAction) { var result = command.exec(editor, e.args || {}); editor.multiSelect.addRange(editor.multiSelect.toOrientedRange()); editor.multiSelect.mergeOverlappingRanges(); } else if (command.multiSelectAction == "forEach") { result = editor.forEachSelection(command, e.args); } else if (command.multiSelectAction == "forEachLine") { result = editor.forEachSelection(command, e.args, true); } else if (command.multiSelectAction == "single") { editor.exitMultiSelectMode(); result = command.exec(editor, e.args || {}); } else { result = command.multiSelectAction(editor, e.args || {}); } return result; }; this.forEachSelection = function(cmd, args, options) { if (this.inVirtualSelectionMode) return; var keepOrder = options && options.keepOrder; var $byLines = options == true || options && options.$byLines var session = this.session; var selection = this.selection; var rangeList = selection.rangeList; var ranges = (keepOrder ? selection : rangeList).ranges; var result; if (!ranges.length) return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {}); var reg = selection._eventRegistry; selection._eventRegistry = {}; var tmpSel = new Selection(session); this.inVirtualSelectionMode = true; for (var i = ranges.length; i--;) { if ($byLines) { while (i > 0 && ranges[i].start.row == ranges[i - 1].end.row) i--; } tmpSel.fromOrientedRange(ranges[i]); tmpSel.index = i; this.selection = session.selection = tmpSel; var cmdResult = cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {}); if (!result && cmdResult !== undefined) result = cmdResult; tmpSel.toOrientedRange(ranges[i]); } tmpSel.detach(); this.selection = session.selection = selection; this.inVirtualSelectionMode = false; selection._eventRegistry = reg; selection.mergeOverlappingRanges(); var anim = this.renderer.$scrollAnimation; this.onCursorChange(); this.onSelectionChange(); if (anim && anim.from == anim.to) this.renderer.animateScrolling(anim.from); return result; }; this.exitMultiSelectMode = function() { if (!this.inMultiSelectMode || this.inVirtualSelectionMode) return; this.multiSelect.toSingleRange(); }; this.getSelectedText = function() { var text = ""; if (this.inMultiSelectMode && !this.inVirtualSelectionMode) { var ranges = this.multiSelect.rangeList.ranges; var buf = []; for (var i = 0; i < ranges.length; i++) { buf.push(this.session.getTextRange(ranges[i])); } var nl = this.session.getDocument().getNewLineCharacter(); text = buf.join(nl); if (text.length == (buf.length - 1) * nl.length) text = ""; } else if (!this.selection.isEmpty()) { text = this.session.getTextRange(this.getSelectionRange()); } return text; }; this.$checkMultiselectChange = function(e, anchor) { if (this.inMultiSelectMode && !this.inVirtualSelectionMode) { var range = this.multiSelect.ranges[0]; if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor) return; var pos = anchor == this.multiSelect.anchor ? range.cursor == range.start ? range.end : range.start : range.cursor; if (!isSamePoint(pos, anchor)) this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange()); } }; this.onPaste = function(text) { if (this.$readOnly) return; var e = {text: text}; this._signal("paste", e); text = e.text; if (!this.inMultiSelectMode || this.inVirtualSelectionMode) return this.insert(text); var lines = text.split(/\r\n|\r|\n/); var ranges = this.selection.rangeList.ranges; if (lines.length > ranges.length || lines.length < 2 || !lines[1]) return this.commands.exec("insertstring", this, text); for (var i = ranges.length; i--;) { var range = ranges[i]; if (!range.isEmpty()) this.session.remove(range); this.session.insert(range.start, lines[i]); } }; this.findAll = function(needle, options, additive) { options = options || {}; options.needle = needle || options.needle; if (options.needle == undefined) { var range = this.selection.isEmpty() ? this.selection.getWordRange() : this.selection.getRange(); options.needle = this.session.getTextRange(range); } this.$search.set(options); var ranges = this.$search.findAll(this.session); if (!ranges.length) return 0; this.$blockScrolling += 1; var selection = this.multiSelect; if (!additive) selection.toSingleRange(ranges[0]); for (var i = ranges.length; i--; ) selection.addRange(ranges[i], true); if (range && selection.rangeList.rangeAtPoint(range.start)) selection.addRange(range, true); this.$blockScrolling -= 1; return ranges.length; }; this.selectMoreLines = function(dir, skip) { var range = this.selection.toOrientedRange(); var isBackwards = range.cursor == range.end; var screenLead = this.session.documentToScreenPosition(range.cursor); if (this.selection.$desiredColumn) screenLead.column = this.selection.$desiredColumn; var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column); if (!range.isEmpty()) { var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start); var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column); } else { var anchor = lead; } if (isBackwards) { var newRange = Range.fromPoints(lead, anchor); newRange.cursor = newRange.start; } else { var newRange = Range.fromPoints(anchor, lead); newRange.cursor = newRange.end; } newRange.desiredColumn = screenLead.column; if (!this.selection.inMultiSelectMode) { this.selection.addRange(range); } else { if (skip) var toRemove = range.cursor; } this.selection.addRange(newRange); if (toRemove) this.selection.substractPoint(toRemove); }; this.transposeSelections = function(dir) { var session = this.session; var sel = session.multiSelect; var all = sel.ranges; for (var i = all.length; i--; ) { var range = all[i]; if (range.isEmpty()) { var tmp = session.getWordRange(range.start.row, range.start.column); range.start.row = tmp.start.row; range.start.column = tmp.start.column; range.end.row = tmp.end.row; range.end.column = tmp.end.column; } } sel.mergeOverlappingRanges(); var words = []; for (var i = all.length; i--; ) { var range = all[i]; words.unshift(session.getTextRange(range)); } if (dir < 0) words.unshift(words.pop()); else words.push(words.shift()); for (var i = all.length; i--; ) { var range = all[i]; var tmp = range.clone(); session.replace(range, words[i]); range.start.row = tmp.start.row; range.start.column = tmp.start.column; } }; this.selectMore = function(dir, skip, stopAtFirst) { var session = this.session; var sel = session.multiSelect; var range = sel.toOrientedRange(); if (range.isEmpty()) { range = session.getWordRange(range.start.row, range.start.column); range.cursor = dir == -1 ? range.start : range.end; this.multiSelect.addRange(range); if (stopAtFirst) return; } var needle = session.getTextRange(range); var newRange = find(session, needle, dir); if (newRange) { newRange.cursor = dir == -1 ? newRange.start : newRange.end; this.$blockScrolling += 1; this.session.unfold(newRange); this.multiSelect.addRange(newRange); this.$blockScrolling -= 1; this.renderer.scrollCursorIntoView(null, 0.5); } if (skip) this.multiSelect.substractPoint(range.cursor); }; this.alignCursors = function() { var session = this.session; var sel = session.multiSelect; var ranges = sel.ranges; var row = -1; var sameRowRanges = ranges.filter(function(r) { if (r.cursor.row == row) return true; row = r.cursor.row; }); if (!ranges.length || sameRowRanges.length == ranges.length - 1) { var range = this.selection.getRange(); var fr = range.start.row, lr = range.end.row; var guessRange = fr == lr; if (guessRange) { var max = this.session.getLength(); var line; do { line = this.session.getLine(lr); } while (/[=:]/.test(line) && ++lr < max); do { line = this.session.getLine(fr); } while (/[=:]/.test(line) && --fr > 0); if (fr < 0) fr = 0; if (lr >= max) lr = max - 1; } var lines = this.session.doc.removeLines(fr, lr); lines = this.$reAlignText(lines, guessRange); this.session.doc.insert({row: fr, column: 0}, lines.join("\n") + "\n"); if (!guessRange) { range.start.column = 0; range.end.column = lines[lines.length - 1].length; } this.selection.setRange(range); } else { sameRowRanges.forEach(function(r) { sel.substractPoint(r.cursor); }); var maxCol = 0; var minSpace = Infinity; var spaceOffsets = ranges.map(function(r) { var p = r.cursor; var line = session.getLine(p.row); var spaceOffset = line.substr(p.column).search(/\S/g); if (spaceOffset == -1) spaceOffset = 0; if (p.column > maxCol) maxCol = p.column; if (spaceOffset < minSpace) minSpace = spaceOffset; return spaceOffset; }); ranges.forEach(function(r, i) { var p = r.cursor; var l = maxCol - p.column; var d = spaceOffsets[i] - minSpace; if (l > d) session.insert(p, lang.stringRepeat(" ", l - d)); else session.remove(new Range(p.row, p.column, p.row, p.column - l + d)); r.start.column = r.end.column = maxCol; r.start.row = r.end.row = p.row; r.cursor = r.end; }); sel.fromOrientedRange(ranges[0]); this.renderer.updateCursor(); this.renderer.updateBackMarkers(); } }; this.$reAlignText = function(lines, forceLeft) { var isLeftAligned = true, isRightAligned = true; var startW, textW, endW; return lines.map(function(line) { var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/); if (!m) return [line]; if (startW == null) { startW = m[1].length; textW = m[2].length; endW = m[3].length; return m; } if (startW + textW + endW != m[1].length + m[2].length + m[3].length) isRightAligned = false; if (startW != m[1].length) isLeftAligned = false; if (startW > m[1].length) startW = m[1].length; if (textW < m[2].length) textW = m[2].length; if (endW > m[3].length) endW = m[3].length; return m; }).map(forceLeft ? alignLeft : isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign); function spaces(n) { return lang.stringRepeat(" ", n); } function alignLeft(m) { return !m[2] ? m[0] : spaces(startW) + m[2] + spaces(textW - m[2].length + endW) + m[4].replace(/^([=:])\s+/, "$1 "); } function alignRight(m) { return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2] + spaces(endW, " ") + m[4].replace(/^([=:])\s+/, "$1 "); } function unAlign(m) { return !m[2] ? m[0] : spaces(startW) + m[2] + spaces(endW) + m[4].replace(/^([=:])\s+/, "$1 "); } }; }).call(Editor.prototype); function isSamePoint(p1, p2) { return p1.row == p2.row && p1.column == p2.column; } exports.onSessionChange = function(e) { var session = e.session; if (session && !session.multiSelect) { session.$selectionMarkers = []; session.selection.$initRangeList(); session.multiSelect = session.selection; } this.multiSelect = session && session.multiSelect; var oldSession = e.oldSession; if (oldSession) { oldSession.multiSelect.off("addRange", this.$onAddRange); oldSession.multiSelect.off("removeRange", this.$onRemoveRange); oldSession.multiSelect.off("multiSelect", this.$onMultiSelect); oldSession.multiSelect.off("singleSelect", this.$onSingleSelect); oldSession.multiSelect.lead.off("change", this.$checkMultiselectChange); oldSession.multiSelect.anchor.off("change", this.$checkMultiselectChange); } if (session) { session.multiSelect.on("addRange", this.$onAddRange); session.multiSelect.on("removeRange", this.$onRemoveRange); session.multiSelect.on("multiSelect", this.$onMultiSelect); session.multiSelect.on("singleSelect", this.$onSingleSelect); session.multiSelect.lead.on("change", this.$checkMultiselectChange); session.multiSelect.anchor.on("change", this.$checkMultiselectChange); } if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) { if (session.selection.inMultiSelectMode) this.$onMultiSelect(); else this.$onSingleSelect(); } }; function MultiSelect(editor) { if (editor.$multiselectOnSessionChange) return; editor.$onAddRange = editor.$onAddRange.bind(editor); editor.$onRemoveRange = editor.$onRemoveRange.bind(editor); editor.$onMultiSelect = editor.$onMultiSelect.bind(editor); editor.$onSingleSelect = editor.$onSingleSelect.bind(editor); editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor); editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor); editor.$multiselectOnSessionChange(editor); editor.on("changeSession", editor.$multiselectOnSessionChange); editor.on("mousedown", onMouseDown); editor.commands.addCommands(commands.defaultCommands); addAltCursorListeners(editor); } function addAltCursorListeners(editor){ var el = editor.textInput.getElement(); var altCursor = false; event.addListener(el, "keydown", function(e) { if (e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey)) { if (!altCursor) { editor.renderer.setMouseCursor("crosshair"); altCursor = true; } } else if (altCursor) { reset(); } }); event.addListener(el, "keyup", reset); event.addListener(el, "blur", reset); function reset(e) { if (altCursor) { editor.renderer.setMouseCursor(""); altCursor = false; } } } exports.MultiSelect = MultiSelect; require("./config").defineOptions(Editor.prototype, "editor", { enableMultiselect: { set: function(val) { MultiSelect(this); if (val) { this.on("changeSession", this.$multiselectOnSessionChange); this.on("mousedown", onMouseDown); } else { this.off("changeSession", this.$multiselectOnSessionChange); this.off("mousedown", onMouseDown); } }, value: true } }); }); ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"], function(require, exports, module) { "use strict"; var Range = require("../../range").Range; var FoldMode = exports.FoldMode = function() {}; (function() { this.foldingStartMarker = null; this.foldingStopMarker = null; this.getFoldWidget = function(session, foldStyle, row) { var line = session.getLine(row); if (this.foldingStartMarker.test(line)) return "start"; if (foldStyle == "markbeginend" && this.foldingStopMarker && this.foldingStopMarker.test(line)) return "end"; return ""; }; this.getFoldWidgetRange = function(session, foldStyle, row) { return null; }; this.indentationBlock = function(session, row, column) { var re = /\S/; var line = session.getLine(row); var startLevel = line.search(re); if (startLevel == -1) return; var startColumn = column || line.length; var maxRow = session.getLength(); var startRow = row; var endRow = row; while (++row < maxRow) { var level = session.getLine(row).search(re); if (level == -1) continue; if (level <= startLevel) break; endRow = row; } if (endRow > startRow) { var endColumn = session.getLine(endRow).length; return new Range(startRow, startColumn, endRow, endColumn); } }; this.openingBracketBlock = function(session, bracket, row, column, typeRe) { var start = {row: row, column: column + 1}; var end = session.$findClosingBracket(bracket, start, typeRe); if (!end) return; var fw = session.foldWidgets[end.row]; if (fw == null) fw = session.getFoldWidget(end.row); if (fw == "start" && end.row > start.row) { end.row --; end.column = session.getLine(end.row).length; } return Range.fromPoints(start, end); }; this.closingBracketBlock = function(session, bracket, row, column, typeRe) { var end = {row: row, column: column}; var start = session.$findOpeningBracket(bracket, end); if (!start) return; start.column++; end.column--; return Range.fromPoints(start, end); }; }).call(FoldMode.prototype); }); ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(require, exports, module) { "use strict"; exports.isDark = false; exports.cssClass = "ace-tm"; exports.cssText = ".ace-tm .ace_gutter {\ background: #f0f0f0;\ color: #333;\ }\ .ace-tm .ace_print-margin {\ width: 1px;\ background: #e8e8e8;\ }\ .ace-tm .ace_fold {\ background-color: #6B72E6;\ }\ .ace-tm {\ background-color: #FFFFFF;\ color: black;\ }\ .ace-tm .ace_cursor {\ color: black;\ }\ .ace-tm .ace_invisible {\ color: rgb(191, 191, 191);\ }\ .ace-tm .ace_storage,\ .ace-tm .ace_keyword {\ color: blue;\ }\ .ace-tm .ace_constant {\ color: rgb(197, 6, 11);\ }\ .ace-tm .ace_constant.ace_buildin {\ color: rgb(88, 72, 246);\ }\ .ace-tm .ace_constant.ace_language {\ color: rgb(88, 92, 246);\ }\ .ace-tm .ace_constant.ace_library {\ color: rgb(6, 150, 14);\ }\ .ace-tm .ace_invalid {\ background-color: rgba(255, 0, 0, 0.1);\ color: red;\ }\ .ace-tm .ace_support.ace_function {\ color: rgb(60, 76, 114);\ }\ .ace-tm .ace_support.ace_constant {\ color: rgb(6, 150, 14);\ }\ .ace-tm .ace_support.ace_type,\ .ace-tm .ace_support.ace_class {\ color: rgb(109, 121, 222);\ }\ .ace-tm .ace_keyword.ace_operator {\ color: rgb(104, 118, 135);\ }\ .ace-tm .ace_string {\ color: rgb(3, 106, 7);\ }\ .ace-tm .ace_comment {\ color: rgb(76, 136, 107);\ }\ .ace-tm .ace_comment.ace_doc {\ color: rgb(0, 102, 255);\ }\ .ace-tm .ace_comment.ace_doc.ace_tag {\ color: rgb(128, 159, 191);\ }\ .ace-tm .ace_constant.ace_numeric {\ color: rgb(0, 0, 205);\ }\ .ace-tm .ace_variable {\ color: rgb(49, 132, 149);\ }\ .ace-tm .ace_xml-pe {\ color: rgb(104, 104, 91);\ }\ .ace-tm .ace_entity.ace_name.ace_function {\ color: #0000A2;\ }\ .ace-tm .ace_heading {\ color: rgb(12, 7, 255);\ }\ .ace-tm .ace_list {\ color:rgb(185, 6, 144);\ }\ .ace-tm .ace_meta.ace_tag {\ color:rgb(0, 22, 142);\ }\ .ace-tm .ace_string.ace_regex {\ color: rgb(255, 0, 0)\ }\ .ace-tm .ace_marker-layer .ace_selection {\ background: rgb(181, 213, 255);\ }\ .ace-tm.ace_multiselect .ace_selection.ace_start {\ box-shadow: 0 0 3px 0px white;\ border-radius: 2px;\ }\ .ace-tm .ace_marker-layer .ace_step {\ background: rgb(252, 255, 0);\ }\ .ace-tm .ace_marker-layer .ace_stack {\ background: rgb(164, 229, 101);\ }\ .ace-tm .ace_marker-layer .ace_bracket {\ margin: -1px 0 0 -1px;\ border: 1px solid rgb(192, 192, 192);\ }\ .ace-tm .ace_marker-layer .ace_active-line {\ background: rgba(0, 0, 0, 0.07);\ }\ .ace-tm .ace_gutter-active-line {\ background-color : #dcdcdc;\ }\ .ace-tm .ace_marker-layer .ace_selected-word {\ background: rgb(250, 250, 255);\ border: 1px solid rgb(200, 200, 250);\ }\ .ace-tm .ace_indent-guide {\ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\ }\ "; var dom = require("../lib/dom"); dom.importCssString(exports.cssText, exports.cssClass); }); ace.define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var dom = require("./lib/dom"); var Range = require("./range").Range; function LineWidgets(session) { this.session = session; this.session.widgetManager = this; this.session.getRowLength = this.getRowLength; this.session.$getWidgetScreenLength = this.$getWidgetScreenLength; this.updateOnChange = this.updateOnChange.bind(this); this.renderWidgets = this.renderWidgets.bind(this); this.measureWidgets = this.measureWidgets.bind(this); this.session._changedWidgets = []; this.$onChangeEditor = this.$onChangeEditor.bind(this); this.session.on("change", this.updateOnChange); this.session.on("changeEditor", this.$onChangeEditor); } (function() { this.getRowLength = function(row) { var h; if (this.lineWidgets) h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; else h = 0; if (!this.$useWrapMode || !this.$wrapData[row]) { return 1 + h; } else { return this.$wrapData[row].length + 1 + h; } }; this.$getWidgetScreenLength = function() { var screenRows = 0; this.lineWidgets.forEach(function(w){ if (w && w.rowCount) screenRows +=w.rowCount; }); return screenRows; }; this.$onChangeEditor = function(e) { this.attach(e.editor); }; this.attach = function(editor) { if (editor && editor.widgetManager && editor.widgetManager != this) editor.widgetManager.detach(); if (this.editor == editor) return; this.detach(); this.editor = editor; if (editor) { editor.widgetManager = this; editor.renderer.on("beforeRender", this.measureWidgets); editor.renderer.on("afterRender", this.renderWidgets); } }; this.detach = function(e) { var editor = this.editor; if (!editor) return; this.editor = null; editor.widgetManager = null; editor.renderer.off("beforeRender", this.measureWidgets); editor.renderer.off("afterRender", this.renderWidgets); var lineWidgets = this.session.lineWidgets; lineWidgets && lineWidgets.forEach(function(w) { if (w && w.el && w.el.parentNode) { w._inDocument = false; w.el.parentNode.removeChild(w.el); } }); }; this.updateOnChange = function(e) { var lineWidgets = this.session.lineWidgets; if (!lineWidgets) return; var delta = e.data; var range = delta.range; var startRow = range.start.row; var len = range.end.row - startRow; if (len === 0) { } else if (delta.action == "removeText" || delta.action == "removeLines") { var removed = lineWidgets.splice(startRow + 1, len); removed.forEach(function(w) { w && this.removeLineWidget(w); }, this); this.$updateRows(); } else { var args = new Array(len); args.unshift(startRow, 0); lineWidgets.splice.apply(lineWidgets, args); this.$updateRows(); } }; this.$updateRows = function() { var lineWidgets = this.session.lineWidgets; if (!lineWidgets) return; var noWidgets = true; lineWidgets.forEach(function(w, i) { if (w) { noWidgets = false; w.row = i; } }); if (noWidgets) this.session.lineWidgets = null; }; this.addLineWidget = function(w) { if (!this.session.lineWidgets) this.session.lineWidgets = new Array(this.session.getLength()); this.session.lineWidgets[w.row] = w; var renderer = this.editor.renderer; if (w.html && !w.el) { w.el = dom.createElement("div"); w.el.innerHTML = w.html; } if (w.el) { dom.addCssClass(w.el, "ace_lineWidgetContainer"); w.el.style.position = "absolute"; w.el.style.zIndex = 5; renderer.container.appendChild(w.el); w._inDocument = true; } if (!w.coverGutter) { w.el.style.zIndex = 3; } if (!w.pixelHeight) { w.pixelHeight = w.el.offsetHeight; } if (w.rowCount == null) w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight; this.session._emit("changeFold", {data:{start:{row: w.row}}}); this.$updateRows(); this.renderWidgets(null, renderer); return w; }; this.removeLineWidget = function(w) { w._inDocument = false; if (w.el && w.el.parentNode) w.el.parentNode.removeChild(w.el); if (w.editor && w.editor.destroy) try { w.editor.destroy(); } catch(e){} if (this.session.lineWidgets) this.session.lineWidgets[w.row] = undefined; this.session._emit("changeFold", {data:{start:{row: w.row}}}); this.$updateRows(); }; this.onWidgetChanged = function(w) { this.session._changedWidgets.push(w); this.editor && this.editor.renderer.updateFull(); }; this.measureWidgets = function(e, renderer) { var changedWidgets = this.session._changedWidgets; var config = renderer.layerConfig; if (!changedWidgets || !changedWidgets.length) return; var min = Infinity; for (var i = 0; i < changedWidgets.length; i++) { var w = changedWidgets[i]; if (!w._inDocument) { w._inDocument = true; renderer.container.appendChild(w.el); } w.h = w.el.offsetHeight; if (!w.fixedWidth) { w.w = w.el.offsetWidth; w.screenWidth = Math.ceil(w.w / config.characterWidth); } var rowCount = w.h / config.lineHeight; if (w.coverLine) { rowCount -= this.session.getRowLineCount(w.row); if (rowCount < 0) rowCount = 0; } if (w.rowCount != rowCount) { w.rowCount = rowCount; if (w.row < min) min = w.row; } } if (min != Infinity) { this.session._emit("changeFold", {data:{start:{row: min}}}); this.session.lineWidgetWidth = null; } this.session._changedWidgets = []; }; this.renderWidgets = function(e, renderer) { var config = renderer.layerConfig; var lineWidgets = this.session.lineWidgets; if (!lineWidgets) return; var first = Math.min(this.firstRow, config.firstRow); var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length); while (first > 0 && !lineWidgets[first]) first--; this.firstRow = config.firstRow; this.lastRow = config.lastRow; renderer.$cursorLayer.config = config; for (var i = first; i <= last; i++) { var w = lineWidgets[i]; if (!w || !w.el) continue; if (!w._inDocument) { w._inDocument = true; renderer.container.appendChild(w.el); } var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top; if (!w.coverLine) top += config.lineHeight * this.session.getRowLineCount(w.row); w.el.style.top = top - config.offset + "px"; var left = w.coverGutter ? 0 : renderer.gutterWidth; if (!w.fixedWidth) left -= renderer.scrollLeft; w.el.style.left = left + "px"; if (w.fixedWidth) { w.el.style.right = renderer.scrollBar.getWidth() + "px"; } else { w.el.style.right = ""; } } }; }).call(LineWidgets.prototype); exports.LineWidgets = LineWidgets; }); ace.define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"], function(require, exports, module) { "use strict"; var LineWidgets = require("../line_widgets").LineWidgets; var dom = require("../lib/dom"); var Range = require("../range").Range; function binarySearch(array, needle, comparator) { var first = 0; var last = array.length - 1; while (first <= last) { var mid = (first + last) >> 1; var c = comparator(needle, array[mid]); if (c > 0) first = mid + 1; else if (c < 0) last = mid - 1; else return mid; } return -(first + 1); } function findAnnotations(session, row, dir) { var annotations = session.getAnnotations().sort(Range.comparePoints); if (!annotations.length) return; var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints); if (i < 0) i = -i - 1; if (i >= annotations.length - 1) i = dir > 0 ? 0 : annotations.length - 1; else if (i === 0 && dir < 0) i = annotations.length - 1; var annotation = annotations[i]; if (!annotation || !dir) return; if (annotation.row === row) { do { annotation = annotations[i += dir]; } while (annotation && annotation.row === row); if (!annotation) return annotations.slice(); } var matched = []; row = annotation.row; do { matched[dir < 0 ? "unshift" : "push"](annotation); annotation = annotations[i += dir]; } while (annotation && annotation.row == row); return matched.length && matched; } exports.showErrorMarker = function(editor, dir) { var session = editor.session; if (!session.widgetManager) { session.widgetManager = new LineWidgets(session); session.widgetManager.attach(editor); } var pos = editor.getCursorPosition(); var row = pos.row; var oldWidget = session.lineWidgets && session.lineWidgets[row]; if (oldWidget) { oldWidget.destroy(); } else { row -= dir; } var annotations = findAnnotations(session, row, dir); var gutterAnno; if (annotations) { var annotation = annotations[0]; pos.column = (annotation.pos && typeof annotation.column != "number" ? annotation.pos.sc : annotation.column) || 0; pos.row = annotation.row; gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row]; } else if (oldWidget) { return; } else { gutterAnno = { text: ["Looks good!"], className: "ace_ok" }; } editor.session.unfold(pos.row); editor.selection.moveToPosition(pos); var w = { row: pos.row, fixedWidth: true, coverGutter: true, el: dom.createElement("div") }; var el = w.el.appendChild(dom.createElement("div")); var arrow = w.el.appendChild(dom.createElement("div")); arrow.className = "error_widget_arrow " + gutterAnno.className; var left = editor.renderer.$cursorLayer .getPixelPosition(pos).left; arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px"; w.el.className = "error_widget_wrapper"; el.className = "error_widget " + gutterAnno.className; el.innerHTML = gutterAnno.text.join("
"); el.appendChild(dom.createElement("div")); var kb = function(_, hashId, keyString) { if (hashId === 0 && (keyString === "esc" || keyString === "return")) { w.destroy(); return {command: "null"}; } }; w.destroy = function() { if (editor.$mouseHandler.isMousePressed) return; editor.keyBinding.removeKeyboardHandler(kb); session.widgetManager.removeLineWidget(w); editor.off("changeSelection", w.destroy); editor.off("changeSession", w.destroy); editor.off("mouseup", w.destroy); editor.off("change", w.destroy); }; editor.keyBinding.addKeyboardHandler(kb); editor.on("changeSelection", w.destroy); editor.on("changeSession", w.destroy); editor.on("mouseup", w.destroy); editor.on("change", w.destroy); editor.session.widgetManager.addLineWidget(w); w.el.onmousedown = editor.focus.bind(editor); editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight}); }; dom.importCssString("\ .error_widget_wrapper {\ background: inherit;\ color: inherit;\ border:none\ }\ .error_widget {\ border-top: solid 2px;\ border-bottom: solid 2px;\ margin: 5px 0;\ padding: 10px 40px;\ white-space: pre-wrap;\ }\ .error_widget.ace_error, .error_widget_arrow.ace_error{\ border-color: #ff5a5a\ }\ .error_widget.ace_warning, .error_widget_arrow.ace_warning{\ border-color: #F1D817\ }\ .error_widget.ace_info, .error_widget_arrow.ace_info{\ border-color: #5a5a5a\ }\ .error_widget.ace_ok, .error_widget_arrow.ace_ok{\ border-color: #5aaa5a\ }\ .error_widget_arrow {\ position: absolute;\ border: solid 5px;\ border-top-color: transparent!important;\ border-right-color: transparent!important;\ border-left-color: transparent!important;\ top: -5px;\ }\ ", ""); }); ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"], function(require, exports, module) { "use strict"; require("./lib/fixoldbrowsers"); var dom = require("./lib/dom"); var event = require("./lib/event"); var Editor = require("./editor").Editor; var EditSession = require("./edit_session").EditSession; var UndoManager = require("./undomanager").UndoManager; var Renderer = require("./virtual_renderer").VirtualRenderer; require("./worker/worker_client"); require("./keyboard/hash_handler"); require("./placeholder"); require("./multi_select"); require("./mode/folding/fold_mode"); require("./theme/textmate"); require("./ext/error_marker"); exports.config = require("./config"); exports.require = require; exports.edit = function(el) { if (typeof(el) == "string") { var _id = el; el = document.getElementById(_id); if (!el) throw new Error("ace.edit can't find div #" + _id); } if (el && el.env && el.env.editor instanceof Editor) return el.env.editor; var value = ""; if (el && /input|textarea/i.test(el.tagName)) { var oldNode = el; value = oldNode.value; el = dom.createElement("pre"); oldNode.parentNode.replaceChild(el, oldNode); } else { value = dom.getInnerText(el); el.innerHTML = ''; } var doc = exports.createEditSession(value); var editor = new Editor(new Renderer(el)); editor.setSession(doc); var env = { document: doc, editor: editor, onResize: editor.resize.bind(editor, null) }; if (oldNode) env.textarea = oldNode; event.addListener(window, "resize", env.onResize); editor.on("destroy", function() { event.removeListener(window, "resize", env.onResize); env.editor.container.env = null; // prevent memory leak on old ie }); editor.container.env = editor.env = env; return editor; }; exports.createEditSession = function(text, mode) { var doc = new EditSession(text, mode); doc.setUndoManager(new UndoManager()); return doc; } exports.EditSession = EditSession; exports.UndoManager = UndoManager; }); (function() { ace.require(["ace/ace"], function(a) { a && a.config.init(true); if (!window.ace) window.ace = a; for (var key in a) if (a.hasOwnProperty(key)) window.ace[key] = a[key]; }); })(); Swagger2-0.89/lib/Swagger2/public/mode-json.js000644 000765 000024 00000055004 12757311624 022254 0ustar00jhthorsenstaff000000 000000 ace.define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var JsonHighlightRules = function() { this.$rules = { "start" : [ { token : "variable", // single line regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)' }, { token : "string", // single line regex : '"', next : "string" }, { token : "constant.numeric", // hex regex : "0[xX][0-9a-fA-F]+\\b" }, { token : "constant.numeric", // float regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" }, { token : "constant.language.boolean", regex : "(?:true|false)\\b" }, { token : "invalid.illegal", // single quoted strings are not allowed regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" }, { token : "invalid.illegal", // comments are not allowed regex : "\\/\\/.*$" }, { token : "paren.lparen", regex : "[[({]" }, { token : "paren.rparen", regex : "[\\])}]" }, { token : "text", regex : "\\s+" } ], "string" : [ { token : "constant.language.escape", regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/ }, { token : "string", regex : '[^"\\\\]+' }, { token : "string", regex : '"', next : "start" }, { token : "string", regex : "", next : "start" } ] }; }; oop.inherits(JsonHighlightRules, TextHighlightRules); exports.JsonHighlightRules = JsonHighlightRules; }); ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { "use strict"; var Range = require("../range").Range; var MatchingBraceOutdent = function() {}; (function() { this.checkOutdent = function(line, input) { if (! /^\s+$/.test(line)) return false; return /^\s*\}/.test(input); }; this.autoOutdent = function(doc, row) { var line = doc.getLine(row); var match = line.match(/^(\s*\})/); if (!match) return 0; var column = match[1].length; var openBracePos = doc.findMatchingBracket({row: row, column: column}); if (!openBracePos || openBracePos.row == row) return 0; var indent = this.$getIndent(doc.getLine(openBracePos.row)); doc.replace(new Range(row, 0, row, column-1), indent); }; this.$getIndent = function(line) { return line.match(/^\s*/)[0]; }; }).call(MatchingBraceOutdent.prototype); exports.MatchingBraceOutdent = MatchingBraceOutdent; }); ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) { "use strict"; var oop = require("../../lib/oop"); var Behaviour = require("../behaviour").Behaviour; var TokenIterator = require("../../token_iterator").TokenIterator; var lang = require("../../lib/lang"); var SAFE_INSERT_IN_TOKENS = ["text", "paren.rparen", "punctuation.operator"]; var SAFE_INSERT_BEFORE_TOKENS = ["text", "paren.rparen", "punctuation.operator", "comment"]; var context; var contextCache = {}; var initContext = function(editor) { var id = -1; if (editor.multiSelect) { id = editor.selection.index; if (contextCache.rangeCount != editor.multiSelect.rangeCount) contextCache = {rangeCount: editor.multiSelect.rangeCount}; } if (contextCache[id]) return context = contextCache[id]; context = contextCache[id] = { autoInsertedBrackets: 0, autoInsertedRow: -1, autoInsertedLineEnd: "", maybeInsertedBrackets: 0, maybeInsertedRow: -1, maybeInsertedLineStart: "", maybeInsertedLineEnd: "" }; }; var CstyleBehaviour = function() { this.add("braces", "insertion", function(state, action, editor, session, text) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); if (text == '{') { initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) { return { text: '{' + selected + '}', selection: false }; } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) { CstyleBehaviour.recordAutoInsert(editor, session, "}"); return { text: '{}', selection: [1, 1] }; } else { CstyleBehaviour.recordMaybeInsert(editor, session, "{"); return { text: '{', selection: [1, 1] }; } } } else if (text == '}') { initContext(editor); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar == '}') { var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row}); if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { CstyleBehaviour.popAutoInsertedClosing(); return { text: '', selection: [1, 1] }; } } } else if (text == "\n" || text == "\r\n") { initContext(editor); var closing = ""; if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) { closing = lang.stringRepeat("}", context.maybeInsertedBrackets); CstyleBehaviour.clearMaybeInsertedClosing(); } var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar === '}') { var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}'); if (!openBracePos) return null; var next_indent = this.$getIndent(session.getLine(openBracePos.row)); } else if (closing) { var next_indent = this.$getIndent(line); } else { CstyleBehaviour.clearMaybeInsertedClosing(); return; } var indent = next_indent + session.getTabString(); return { text: '\n' + indent + '\n' + next_indent + closing, selection: [1, indent.length, 1, indent.length] }; } else { CstyleBehaviour.clearMaybeInsertedClosing(); } }); this.add("braces", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected == '{') { initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.end.column, range.end.column + 1); if (rightChar == '}') { range.end.column++; return range; } else { context.maybeInsertedBrackets--; } } }); this.add("parens", "insertion", function(state, action, editor, session, text) { if (text == '(') { initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && editor.getWrapBehavioursEnabled()) { return { text: '(' + selected + ')', selection: false }; } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { CstyleBehaviour.recordAutoInsert(editor, session, ")"); return { text: '()', selection: [1, 1] }; } } else if (text == ')') { initContext(editor); var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar == ')') { var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row}); if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { CstyleBehaviour.popAutoInsertedClosing(); return { text: '', selection: [1, 1] }; } } } }); this.add("parens", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected == '(') { initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar == ')') { range.end.column++; return range; } } }); this.add("brackets", "insertion", function(state, action, editor, session, text) { if (text == '[') { initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && editor.getWrapBehavioursEnabled()) { return { text: '[' + selected + ']', selection: false }; } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { CstyleBehaviour.recordAutoInsert(editor, session, "]"); return { text: '[]', selection: [1, 1] }; } } else if (text == ']') { initContext(editor); var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar == ']') { var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row}); if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { CstyleBehaviour.popAutoInsertedClosing(); return { text: '', selection: [1, 1] }; } } } }); this.add("brackets", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected == '[') { initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar == ']') { range.end.column++; return range; } } }); this.add("string_dquotes", "insertion", function(state, action, editor, session, text) { if (text == '"' || text == "'") { initContext(editor); var quote = text; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { return { text: quote + selected + quote, selection: false }; } else { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var leftChar = line.substring(cursor.column-1, cursor.column); if (leftChar == '\\') { return null; } var tokens = session.getTokens(selection.start.row); 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(quote); } if ((token.value.length + col) > selection.start.column) { break; } col += tokens[x].value.length; } if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf(quote) === token.value.length-1)))) { if (!CstyleBehaviour.isSaneInsertion(editor, session)) return; return { text: quote + quote, selection: [1,1] }; } else if (token && token.type === "string") { var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar == quote) { return { text: '', selection: [1, 1] }; } } } } }); this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && (selected == '"' || selected == "'")) { initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar == selected) { range.end.column++; return range; } } }); }; CstyleBehaviour.isSaneInsertion = function(editor, session) { var cursor = editor.getCursorPosition(); var iterator = new TokenIterator(session, cursor.row, cursor.column); if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) { var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1); if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) return false; } iterator.stepForward(); return iterator.getCurrentTokenRow() !== cursor.row || this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS); }; CstyleBehaviour.$matchTokenType = function(token, types) { return types.indexOf(token.type || token) > -1; }; CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0])) context.autoInsertedBrackets = 0; context.autoInsertedRow = cursor.row; context.autoInsertedLineEnd = bracket + line.substr(cursor.column); context.autoInsertedBrackets++; }; CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); if (!this.isMaybeInsertedClosing(cursor, line)) context.maybeInsertedBrackets = 0; context.maybeInsertedRow = cursor.row; context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket; context.maybeInsertedLineEnd = line.substr(cursor.column); context.maybeInsertedBrackets++; }; CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { return context.autoInsertedBrackets > 0 && cursor.row === context.autoInsertedRow && bracket === context.autoInsertedLineEnd[0] && line.substr(cursor.column) === context.autoInsertedLineEnd; }; CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) { return context.maybeInsertedBrackets > 0 && cursor.row === context.maybeInsertedRow && line.substr(cursor.column) === context.maybeInsertedLineEnd && line.substr(0, cursor.column) == context.maybeInsertedLineStart; }; CstyleBehaviour.popAutoInsertedClosing = function() { context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1); context.autoInsertedBrackets--; }; CstyleBehaviour.clearMaybeInsertedClosing = function() { if (context) { context.maybeInsertedBrackets = 0; context.maybeInsertedRow = -1; } }; oop.inherits(CstyleBehaviour, Behaviour); exports.CstyleBehaviour = CstyleBehaviour; }); ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { "use strict"; var oop = require("../../lib/oop"); var Range = require("../../range").Range; var BaseFoldMode = require("./fold_mode").FoldMode; var FoldMode = exports.FoldMode = function(commentRegex) { if (commentRegex) { this.foldingStartMarker = new RegExp( this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) ); this.foldingStopMarker = new RegExp( this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) ); } }; oop.inherits(FoldMode, BaseFoldMode); (function() { this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/; this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/; this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { var line = session.getLine(row); var match = line.match(this.foldingStartMarker); if (match) { var i = match.index; if (match[1]) return this.openingBracketBlock(session, match[1], row, i); var range = session.getCommentFoldRange(row, i + match[0].length, 1); if (range && !range.isMultiLine()) { if (forceMultiline) { range = this.getSectionRange(session, row); } else if (foldStyle != "all") range = null; } return range; } if (foldStyle === "markbegin") return; var match = line.match(this.foldingStopMarker); if (match) { var i = match.index + match[0].length; if (match[1]) return this.closingBracketBlock(session, match[1], row, i); return session.getCommentFoldRange(row, i, -1); } }; this.getSectionRange = function(session, row) { var line = session.getLine(row); var startIndent = line.search(/\S/); var startRow = row; var startColumn = line.length; row = row + 1; var endRow = row; var maxRow = session.getLength(); while (++row < maxRow) { line = session.getLine(row); var indent = line.search(/\S/); if (indent === -1) continue; if (startIndent > indent) break; var subRange = this.getFoldWidgetRange(session, "all", row); if (subRange) { if (subRange.start.row <= startRow) { break; } else if (subRange.isMultiLine()) { row = subRange.end.row; } else if (startIndent == indent) { break; } } endRow = row; } return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); }; }).call(FoldMode.prototype); }); ace.define("ace/mode/json",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/json_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/worker/worker_client"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var HighlightRules = require("./json_highlight_rules").JsonHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; var CStyleFoldMode = require("./folding/cstyle").FoldMode; var WorkerClient = require("../worker/worker_client").WorkerClient; var Mode = function() { this.HighlightRules = HighlightRules; this.$outdent = new MatchingBraceOutdent(); this.$behaviour = new CstyleBehaviour(); this.foldingRules = new CStyleFoldMode(); }; oop.inherits(Mode, TextMode); (function() { this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); if (state == "start") { var match = line.match(/^.*[\{\(\[]\s*$/); if (match) { indent += tab; } } return indent; }; this.checkOutdent = function(state, line, input) { return this.$outdent.checkOutdent(line, input); }; this.autoOutdent = function(state, doc, row) { this.$outdent.autoOutdent(doc, row); }; this.createWorker = function(session) { var worker = new WorkerClient(["ace"], "ace/mode/json_worker", "JsonWorker"); worker.attachToDocument(session.getDocument()); worker.on("error", function(e) { session.setAnnotations([e.data]); }); worker.on("ok", function() { session.clearAnnotations(); }); return worker; }; this.$id = "ace/mode/json"; }).call(Mode.prototype); exports.Mode = Mode; }); Swagger2-0.89/lib/Swagger2/public/mode-yaml.js000644 000765 000024 00000017313 12757311624 022246 0ustar00jhthorsenstaff000000 000000 ace.define("ace/mode/yaml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var YamlHighlightRules = function() { this.$rules = { "start" : [ { token : "comment", regex : "#.*$" }, { token : "list.markup", regex : /^(?:-{3}|\.{3})\s*(?=#|$)/ }, { token : "list.markup", regex : /^\s*[\-?](?:$|\s)/ }, { token: "constant", regex: "!![\\w//]+" }, { token: "constant.language", regex: "[&\\*][a-zA-Z0-9-_]+" }, { token: ["meta.tag", "keyword"], regex: /^(\s*\w.*?)(\:(?:\s+|$))/ },{ token: ["meta.tag", "keyword"], regex: /(\w+?)(\s*\:(?:\s+|$))/ }, { token : "keyword.operator", regex : "<<\\w*:\\w*" }, { token : "keyword.operator", regex : "-\\s*(?=[{])" }, { token : "string", // single line regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' }, { token : "string", // multi line string start regex : '[|>][-+\\d\\s]*$', next : "qqstring" }, { token : "string", // single quoted string regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" }, { token : "constant.numeric", // float regex : /(\b|[+\-\.])[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)/ }, { token : "constant.numeric", // other number regex : /[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/ }, { token : "constant.language.boolean", regex : "(?:true|false|TRUE|FALSE|True|False|yes|no)\\b" }, { token : "paren.lparen", regex : "[[({]" }, { token : "paren.rparen", regex : "[\\])}]" } ], "qqstring" : [ { token : "string", regex : '(?=(?:(?:\\\\.)|(?:[^:]))*?:)', next : "start" }, { token : "string", regex : '.+' } ]}; }; oop.inherits(YamlHighlightRules, TextHighlightRules); exports.YamlHighlightRules = YamlHighlightRules; }); ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { "use strict"; var Range = require("../range").Range; var MatchingBraceOutdent = function() {}; (function() { this.checkOutdent = function(line, input) { if (! /^\s+$/.test(line)) return false; return /^\s*\}/.test(input); }; this.autoOutdent = function(doc, row) { var line = doc.getLine(row); var match = line.match(/^(\s*\})/); if (!match) return 0; var column = match[1].length; var openBracePos = doc.findMatchingBracket({row: row, column: column}); if (!openBracePos || openBracePos.row == row) return 0; var indent = this.$getIndent(doc.getLine(openBracePos.row)); doc.replace(new Range(row, 0, row, column-1), indent); }; this.$getIndent = function(line) { return line.match(/^\s*/)[0]; }; }).call(MatchingBraceOutdent.prototype); exports.MatchingBraceOutdent = MatchingBraceOutdent; }); ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"], function(require, exports, module) { "use strict"; var oop = require("../../lib/oop"); var BaseFoldMode = require("./fold_mode").FoldMode; var Range = require("../../range").Range; var FoldMode = exports.FoldMode = function() {}; oop.inherits(FoldMode, BaseFoldMode); (function() { this.getFoldWidgetRange = function(session, foldStyle, row) { var range = this.indentationBlock(session, row); if (range) return range; var re = /\S/; var line = session.getLine(row); var startLevel = line.search(re); if (startLevel == -1 || line[startLevel] != "#") return; var startColumn = line.length; var maxRow = session.getLength(); var startRow = row; var endRow = row; while (++row < maxRow) { line = session.getLine(row); var level = line.search(re); if (level == -1) continue; if (line[level] != "#") break; endRow = row; } if (endRow > startRow) { var endColumn = session.getLine(endRow).length; return new Range(startRow, startColumn, endRow, endColumn); } }; this.getFoldWidget = function(session, foldStyle, row) { var line = session.getLine(row); var indent = line.search(/\S/); var next = session.getLine(row + 1); var prev = session.getLine(row - 1); var prevIndent = prev.search(/\S/); var nextIndent = next.search(/\S/); if (indent == -1) { session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : ""; return ""; } if (prevIndent == -1) { if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") { session.foldWidgets[row - 1] = ""; session.foldWidgets[row + 1] = ""; return "start"; } } else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") { if (session.getLine(row - 2).search(/\S/) == -1) { session.foldWidgets[row - 1] = "start"; session.foldWidgets[row + 1] = ""; return ""; } } if (prevIndent!= -1 && prevIndent < indent) session.foldWidgets[row - 1] = "start"; else session.foldWidgets[row - 1] = ""; if (indent < nextIndent) return "start"; else return ""; }; }).call(FoldMode.prototype); }); ace.define("ace/mode/yaml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/yaml_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/coffee"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var YamlHighlightRules = require("./yaml_highlight_rules").YamlHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = YamlHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.foldingRules = new FoldMode(); }; oop.inherits(Mode, TextMode); (function() { this.lineCommentStart = "#"; this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); if (state == "start") { var match = line.match(/^.*[\{\(\[]\s*$/); if (match) { indent += tab; } } return indent; }; this.checkOutdent = function(state, line, input) { return this.$outdent.checkOutdent(line, input); }; this.autoOutdent = function(state, doc, row) { this.$outdent.autoOutdent(doc, row); }; this.$id = "ace/mode/yaml"; }).call(Mode.prototype); exports.Mode = Mode; }); Swagger2-0.89/lib/Swagger2/public/theme-solarized_dark.js000644 000765 000024 00000005015 12757311624 024453 0ustar00jhthorsenstaff000000 000000 ace.define("ace/theme/solarized_dark",["require","exports","module","ace/lib/dom"], function(require, exports, module) { exports.isDark = true; exports.cssClass = "ace-solarized-dark"; exports.cssText = ".ace-solarized-dark .ace_gutter {\ background: #01313f;\ color: #d0edf7\ }\ .ace-solarized-dark .ace_print-margin {\ width: 1px;\ background: #33555E\ }\ .ace-solarized-dark {\ background-color: #002B36;\ color: #93A1A1\ }\ .ace-solarized-dark .ace_entity.ace_other.ace_attribute-name,\ .ace-solarized-dark .ace_storage {\ color: #93A1A1\ }\ .ace-solarized-dark .ace_cursor,\ .ace-solarized-dark .ace_string.ace_regexp {\ color: #D30102\ }\ .ace-solarized-dark .ace_marker-layer .ace_active-line,\ .ace-solarized-dark .ace_marker-layer .ace_selection {\ background: rgba(255, 255, 255, 0.1)\ }\ .ace-solarized-dark.ace_multiselect .ace_selection.ace_start {\ box-shadow: 0 0 3px 0px #002B36;\ border-radius: 2px\ }\ .ace-solarized-dark .ace_marker-layer .ace_step {\ background: rgb(102, 82, 0)\ }\ .ace-solarized-dark .ace_marker-layer .ace_bracket {\ margin: -1px 0 0 -1px;\ border: 1px solid rgba(147, 161, 161, 0.50)\ }\ .ace-solarized-dark .ace_gutter-active-line {\ background-color: #0d3440\ }\ .ace-solarized-dark .ace_marker-layer .ace_selected-word {\ border: 1px solid #073642\ }\ .ace-solarized-dark .ace_invisible {\ color: rgba(147, 161, 161, 0.50)\ }\ .ace-solarized-dark .ace_keyword,\ .ace-solarized-dark .ace_meta,\ .ace-solarized-dark .ace_support.ace_class,\ .ace-solarized-dark .ace_support.ace_type {\ color: #859900\ }\ .ace-solarized-dark .ace_constant.ace_character,\ .ace-solarized-dark .ace_constant.ace_other {\ color: #CB4B16\ }\ .ace-solarized-dark .ace_constant.ace_language {\ color: #B58900\ }\ .ace-solarized-dark .ace_constant.ace_numeric {\ color: #D33682\ }\ .ace-solarized-dark .ace_fold {\ background-color: #268BD2;\ border-color: #93A1A1\ }\ .ace-solarized-dark .ace_entity.ace_name.ace_function,\ .ace-solarized-dark .ace_entity.ace_name.ace_tag,\ .ace-solarized-dark .ace_support.ace_function,\ .ace-solarized-dark .ace_variable,\ .ace-solarized-dark .ace_variable.ace_language {\ color: #268BD2\ }\ .ace-solarized-dark .ace_string {\ color: #2AA198\ }\ .ace-solarized-dark .ace_comment {\ font-style: italic;\ color: #657B83\ }\ .ace-solarized-dark .ace_indent-guide {\ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNg0Db1ZVCxc/sPAAd4AlUHlLenAAAAAElFTkSuQmCC) right repeat-y\ }"; var dom = require("../lib/dom"); dom.importCssString(exports.cssText, exports.cssClass); }); Swagger2-0.89/lib/Swagger2/public/worker-json.js000644 000765 000024 00000206240 12757311624 022641 0ustar00jhthorsenstaff000000 000000 "no use strict"; ;(function(window) { if (typeof window.window != "undefined" && window.document) { return; } window.console = function() { var msgs = Array.prototype.slice.call(arguments, 0); postMessage({type: "log", data: msgs}); }; window.console.error = window.console.warn = window.console.log = window.console.trace = window.console; window.window = window; window.ace = window; window.onerror = function(message, file, line, col, err) { postMessage({type: "error", data: { message: message, file: file, line: line, col: col, stack: err.stack }}); }; window.normalizeModule = function(parentId, moduleName) { // normalize plugin requires if (moduleName.indexOf("!") !== -1) { var chunks = moduleName.split("!"); return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]); } // normalize relative requires if (moduleName.charAt(0) == ".") { var base = parentId.split("/").slice(0, -1).join("/"); moduleName = (base ? base + "/" : "") + moduleName; while(moduleName.indexOf(".") !== -1 && previous != moduleName) { var previous = moduleName; moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); } } return moduleName; }; window.require = function(parentId, id) { if (!id) { id = parentId; parentId = null; } if (!id.charAt) throw new Error("worker.js require() accepts only (parentId, id) as arguments"); id = window.normalizeModule(parentId, id); var module = window.require.modules[id]; if (module) { if (!module.initialized) { module.initialized = true; module.exports = module.factory().exports; } return module.exports; } var chunks = id.split("/"); if (!window.require.tlns) return console.log("unable to load " + id); chunks[0] = window.require.tlns[chunks[0]] || chunks[0]; var path = chunks.join("/") + ".js"; window.require.id = id; importScripts(path); return window.require(parentId, id); }; window.require.modules = {}; window.require.tlns = {}; window.define = function(id, deps, factory) { if (arguments.length == 2) { factory = deps; if (typeof id != "string") { deps = id; id = window.require.id; } } else if (arguments.length == 1) { factory = id; deps = []; id = window.require.id; } if (typeof factory != "function") { window.require.modules[id] = { exports: factory, initialized: true }; return; } if (!deps.length) // If there is no dependencies, we inject 'require', 'exports' and // 'module' as dependencies, to provide CommonJS compatibility. deps = ['require', 'exports', 'module']; var req = function(childId) { return window.require(id, childId); }; window.require.modules[id] = { exports: {}, factory: function() { var module = this; var returnExports = factory.apply(this, deps.map(function(dep) { switch(dep) { // Because 'require', 'exports' and 'module' aren't actual // dependencies, we must handle them seperately. case 'require': return req; case 'exports': return module.exports; case 'module': return module; // But for all other dependencies, we can just go ahead and // require them. default: return req(dep); } })); if (returnExports) module.exports = returnExports; return module; } }; }; window.define.amd = {}; window.initBaseUrls = function initBaseUrls(topLevelNamespaces) { require.tlns = topLevelNamespaces; }; window.initSender = function initSender() { var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter; var oop = window.require("ace/lib/oop"); var Sender = function() {}; (function() { oop.implement(this, EventEmitter); this.callback = function(data, callbackId) { postMessage({ type: "call", id: callbackId, data: data }); }; this.emit = function(name, data) { postMessage({ type: "event", name: name, data: data }); }; }).call(Sender.prototype); return new Sender(); }; var main = window.main = null; var sender = window.sender = null; window.onmessage = function(e) { var msg = e.data; if (msg.command) { if (main[msg.command]) main[msg.command].apply(main, msg.args); else throw new Error("Unknown command:" + msg.command); } else if (msg.init) { initBaseUrls(msg.tlns); require("ace/lib/es5-shim"); sender = window.sender = initSender(); var clazz = require(msg.module)[msg.classname]; main = window.main = new clazz(sender); } else if (msg.event && sender) { sender._signal(msg.event, msg.data); } }; })(this); ace.define("ace/lib/oop",["require","exports","module"], function(require, exports, module) { "use strict"; exports.inherits = function(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; exports.mixin = function(obj, mixin) { for (var key in mixin) { obj[key] = mixin[key]; } return obj; }; exports.implement = function(proto, mixin) { exports.mixin(proto, mixin); }; }); ace.define("ace/lib/event_emitter",["require","exports","module"], function(require, exports, module) { "use strict"; var EventEmitter = {}; var stopPropagation = function() { this.propagationStopped = true; }; var preventDefault = function() { this.defaultPrevented = true; }; EventEmitter._emit = EventEmitter._dispatchEvent = function(eventName, e) { this._eventRegistry || (this._eventRegistry = {}); this._defaultHandlers || (this._defaultHandlers = {}); var listeners = this._eventRegistry[eventName] || []; var defaultHandler = this._defaultHandlers[eventName]; if (!listeners.length && !defaultHandler) return; if (typeof e != "object" || !e) e = {}; if (!e.type) e.type = eventName; if (!e.stopPropagation) e.stopPropagation = stopPropagation; if (!e.preventDefault) e.preventDefault = preventDefault; listeners = listeners.slice(); for (var i=0; i [" + this.end.row + "/" + this.end.column + "]"); }; this.contains = function(row, column) { return this.compare(row, column) == 0; }; this.compareRange = function(range) { var cmp, end = range.end, start = range.start; cmp = this.compare(end.row, end.column); if (cmp == 1) { cmp = this.compare(start.row, start.column); if (cmp == 1) { return 2; } else if (cmp == 0) { return 1; } else { return 0; } } else if (cmp == -1) { return -2; } else { cmp = this.compare(start.row, start.column); if (cmp == -1) { return -1; } else if (cmp == 1) { return 42; } else { return 0; } } }; this.comparePoint = function(p) { return this.compare(p.row, p.column); }; this.containsRange = function(range) { return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0; }; this.intersects = function(range) { var cmp = this.compareRange(range); return (cmp == -1 || cmp == 0 || cmp == 1); }; this.isEnd = function(row, column) { return this.end.row == row && this.end.column == column; }; this.isStart = function(row, column) { return this.start.row == row && this.start.column == column; }; this.setStart = function(row, column) { if (typeof row == "object") { this.start.column = row.column; this.start.row = row.row; } else { this.start.row = row; this.start.column = column; } }; this.setEnd = function(row, column) { if (typeof row == "object") { this.end.column = row.column; this.end.row = row.row; } else { this.end.row = row; this.end.column = column; } }; this.inside = function(row, column) { if (this.compare(row, column) == 0) { if (this.isEnd(row, column) || this.isStart(row, column)) { return false; } else { return true; } } return false; }; this.insideStart = function(row, column) { if (this.compare(row, column) == 0) { if (this.isEnd(row, column)) { return false; } else { return true; } } return false; }; this.insideEnd = function(row, column) { if (this.compare(row, column) == 0) { if (this.isStart(row, column)) { return false; } else { return true; } } return false; }; this.compare = function(row, column) { if (!this.isMultiLine()) { if (row === this.start.row) { return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0); }; } if (row < this.start.row) return -1; if (row > this.end.row) return 1; if (this.start.row === row) return column >= this.start.column ? 0 : -1; if (this.end.row === row) return column <= this.end.column ? 0 : 1; return 0; }; this.compareStart = function(row, column) { if (this.start.row == row && this.start.column == column) { return -1; } else { return this.compare(row, column); } }; this.compareEnd = function(row, column) { if (this.end.row == row && this.end.column == column) { return 1; } else { return this.compare(row, column); } }; this.compareInside = function(row, column) { if (this.end.row == row && this.end.column == column) { return 1; } else if (this.start.row == row && this.start.column == column) { return -1; } else { return this.compare(row, column); } }; this.clipRows = function(firstRow, lastRow) { if (this.end.row > lastRow) var end = {row: lastRow + 1, column: 0}; else if (this.end.row < firstRow) var end = {row: firstRow, column: 0}; if (this.start.row > lastRow) var start = {row: lastRow + 1, column: 0}; else if (this.start.row < firstRow) var start = {row: firstRow, column: 0}; return Range.fromPoints(start || this.start, end || this.end); }; this.extend = function(row, column) { var cmp = this.compare(row, column); if (cmp == 0) return this; else if (cmp == -1) var start = {row: row, column: column}; else var end = {row: row, column: column}; return Range.fromPoints(start || this.start, end || this.end); }; this.isEmpty = function() { return (this.start.row === this.end.row && this.start.column === this.end.column); }; this.isMultiLine = function() { return (this.start.row !== this.end.row); }; this.clone = function() { return Range.fromPoints(this.start, this.end); }; this.collapseRows = function() { if (this.end.column == 0) return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0) else return new Range(this.start.row, 0, this.end.row, 0) }; this.toScreenRange = function(session) { var screenPosStart = session.documentToScreenPosition(this.start); var screenPosEnd = session.documentToScreenPosition(this.end); return new Range( screenPosStart.row, screenPosStart.column, screenPosEnd.row, screenPosEnd.column ); }; this.moveBy = function(row, column) { this.start.row += row; this.start.column += column; this.end.row += row; this.end.column += column; }; }).call(Range.prototype); Range.fromPoints = function(start, end) { return new Range(start.row, start.column, end.row, end.column); }; Range.comparePoints = comparePoints; Range.comparePoints = function(p1, p2) { return p1.row - p2.row || p1.column - p2.column; }; exports.Range = Range; }); ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var Anchor = exports.Anchor = function(doc, row, column) { this.$onChange = this.onChange.bind(this); this.attach(doc); if (typeof column == "undefined") this.setPosition(row.row, row.column); else this.setPosition(row, column); }; (function() { oop.implement(this, EventEmitter); this.getPosition = function() { return this.$clipPositionToDocument(this.row, this.column); }; this.getDocument = function() { return this.document; }; this.$insertRight = false; 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; var start = range.start; var end = range.end; if (delta.action === "insertText") { if (start.row === row && start.column <= column) { if (start.column === column && this.$insertRight) { } else if (start.row === end.row) { column += end.column - start.column; } else { column -= start.column; row += end.row - start.row; } } else if (start.row !== end.row && start.row < row) { row += end.row - start.row; } } else if (delta.action === "insertLines") { if (start.row === row && column === 0 && this.$insertRight) { } else if (start.row <= row) { row += end.row - start.row; } } else if (delta.action === "removeText") { if (start.row === row && start.column < column) { if (end.column >= column) column = start.column; else column = Math.max(0, column - (end.column - start.column)); } else if (start.row !== end.row && start.row < row) { if (end.row === row) column = Math.max(0, column - end.column) + start.column; row -= (end.row - start.row); } else if (end.row === row) { row -= end.row - start.row; column = Math.max(0, column - end.column) + start.column; } } else if (delta.action == "removeLines") { if (start.row <= row) { if (end.row <= row) row -= end.row - start.row; else { row = 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._signal("change", { old: old, value: pos }); }; this.detach = function() { this.document.removeEventListener("change", this.$onChange); }; this.attach = function(doc) { this.document = doc || this.document; this.document.on("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); }); ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"], function(require, exports, module) { "use strict"; var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var Range = require("./range").Range; var Anchor = require("./anchor").Anchor; var Document = function(text) { this.$lines = []; if (text.length === 0) { this.$lines = [""]; } else if (Array.isArray(text)) { this._insertLines(0, text); } else { this.insert({row: 0, column:0}, text); } }; (function() { oop.implement(this, EventEmitter); this.setValue = function(text) { var len = this.getLength(); this.remove(new Range(0, 0, len, this.getLine(len-1).length)); this.insert({row: 0, column:0}, text); }; this.getValue = function() { return this.getAllLines().join(this.getNewLineCharacter()); }; this.createAnchor = function(row, column) { return new Anchor(this, row, column); }; if ("aaa".split(/a/).length === 0) this.$split = function(text) { return text.replace(/\r\n|\r/g, "\n").split("\n"); }; else this.$split = function(text) { return text.split(/\r\n|\r|\n/); }; this.$detectNewLine = function(text) { var match = text.match(/^.*?(\r\n|\r|\n)/m); this.$autoNewLine = match ? match[1] : "\n"; this._signal("changeNewLineMode"); }; this.getNewLineCharacter = function() { switch (this.$newLineMode) { case "windows": return "\r\n"; case "unix": return "\n"; default: return this.$autoNewLine || "\n"; } }; this.$autoNewLine = ""; this.$newLineMode = "auto"; this.setNewLineMode = function(newLineMode) { if (this.$newLineMode === newLineMode) return; this.$newLineMode = newLineMode; this._signal("changeNewLineMode"); }; this.getNewLineMode = function() { return this.$newLineMode; }; this.isNewLine = function(text) { return (text == "\r\n" || text == "\r" || text == "\n"); }; this.getLine = function(row) { return this.$lines[row] || ""; }; this.getLines = function(firstRow, lastRow) { return this.$lines.slice(firstRow, lastRow + 1); }; this.getAllLines = function() { return this.getLines(0, this.getLength()); }; this.getLength = function() { return this.$lines.length; }; this.getTextRange = function(range) { if (range.start.row == range.end.row) { return this.getLine(range.start.row) .substring(range.start.column, range.end.column); } var lines = this.getLines(range.start.row, range.end.row); lines[0] = (lines[0] || "").substring(range.start.column); var l = lines.length - 1; if (range.end.row - range.start.row == l) lines[l] = lines[l].substring(0, range.end.column); return lines.join(this.getNewLineCharacter()); }; this.$clipPosition = function(position) { var length = this.getLength(); if (position.row >= length) { position.row = Math.max(0, length - 1); position.column = this.getLine(length-1).length; } else if (position.row < 0) position.row = 0; return position; }; this.insert = function(position, text) { if (!text || text.length === 0) return position; position = this.$clipPosition(position); if (this.getLength() <= 1) this.$detectNewLine(text); var lines = this.$split(text); var firstLine = lines.splice(0, 1)[0]; var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0]; position = this.insertInLine(position, firstLine); if (lastLine !== null) { position = this.insertNewLine(position); // terminate first line position = this._insertLines(position.row, lines); position = this.insertInLine(position, lastLine || ""); } return position; }; this.insertLines = function(row, lines) { if (row >= this.getLength()) return this.insert({row: row, column: 0}, "\n" + lines.join("\n")); return this._insertLines(Math.max(row, 0), lines); }; this._insertLines = function(row, lines) { if (lines.length == 0) return {row: row, column: 0}; while (lines.length > 0xF000) { var end = this._insertLines(row, lines.slice(0, 0xF000)); lines = lines.slice(0xF000); row = end.row; } var args = [row, 0]; args.push.apply(args, lines); this.$lines.splice.apply(this.$lines, args); var range = new Range(row, 0, row + lines.length, 0); var delta = { action: "insertLines", range: range, lines: lines }; this._signal("change", { data: delta }); return range.end; }; this.insertNewLine = function(position) { position = this.$clipPosition(position); var line = this.$lines[position.row] || ""; this.$lines[position.row] = line.substring(0, position.column); this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length)); var end = { row : position.row + 1, column : 0 }; var delta = { action: "insertText", range: Range.fromPoints(position, end), text: this.getNewLineCharacter() }; this._signal("change", { data: delta }); return end; }; this.insertInLine = function(position, text) { if (text.length == 0) return position; var line = this.$lines[position.row] || ""; this.$lines[position.row] = line.substring(0, position.column) + text + line.substring(position.column); var end = { row : position.row, column : position.column + text.length }; var delta = { action: "insertText", range: Range.fromPoints(position, end), text: text }; this._signal("change", { data: delta }); return end; }; this.remove = function(range) { if (!(range instanceof Range)) range = Range.fromPoints(range.start, range.end); range.start = this.$clipPosition(range.start); range.end = this.$clipPosition(range.end); if (range.isEmpty()) return range.start; var firstRow = range.start.row; var lastRow = range.end.row; if (range.isMultiLine()) { var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1; var lastFullRow = lastRow - 1; if (range.end.column > 0) this.removeInLine(lastRow, 0, range.end.column); if (lastFullRow >= firstFullRow) this._removeLines(firstFullRow, lastFullRow); if (firstFullRow != firstRow) { this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length); this.removeNewLine(range.start.row); } } else { this.removeInLine(firstRow, range.start.column, range.end.column); } return range.start; }; this.removeInLine = function(row, startColumn, endColumn) { if (startColumn == endColumn) return; var range = new Range(row, startColumn, row, endColumn); var line = this.getLine(row); var removed = line.substring(startColumn, endColumn); var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length); this.$lines.splice(row, 1, newLine); var delta = { action: "removeText", range: range, text: removed }; this._signal("change", { data: delta }); return range.start; }; this.removeLines = function(firstRow, lastRow) { if (firstRow < 0 || lastRow >= this.getLength()) return this.remove(new Range(firstRow, 0, lastRow + 1, 0)); return this._removeLines(firstRow, lastRow); }; this._removeLines = function(firstRow, lastRow) { var range = new Range(firstRow, 0, lastRow + 1, 0); var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1); var delta = { action: "removeLines", range: range, nl: this.getNewLineCharacter(), lines: removed }; this._signal("change", { data: delta }); return removed; }; this.removeNewLine = function(row) { var firstLine = this.getLine(row); var secondLine = this.getLine(row+1); var range = new Range(row, firstLine.length, row+1, 0); var line = firstLine + secondLine; this.$lines.splice(row, 2, line); var delta = { action: "removeText", range: range, text: this.getNewLineCharacter() }; this._signal("change", { data: delta }); }; this.replace = function(range, text) { if (!(range instanceof Range)) range = Range.fromPoints(range.start, range.end); if (text.length == 0 && range.isEmpty()) return range.start; if (text == this.getTextRange(range)) return range.end; this.remove(range); if (text) { var end = this.insert(range.start, text); } else { end = range.start; } return end; }; this.applyDeltas = function(deltas) { for (var i=0; i=0; i--) { var delta = deltas[i]; var range = Range.fromPoints(delta.range.start, delta.range.end); if (delta.action == "insertLines") this._removeLines(range.start.row, range.end.row - 1); else if (delta.action == "insertText") this.remove(range); else if (delta.action == "removeLines") this._insertLines(range.start.row, delta.lines); else if (delta.action == "removeText") this.insert(range.start, delta.text); } }; this.indexToPosition = function(index, startRow) { var lines = this.$lines || this.getAllLines(); var newlineLength = this.getNewLineCharacter().length; for (var i = startRow || 0, l = lines.length; i < l; i++) { index -= lines[i].length + newlineLength; if (index < 0) return {row: i, column: index + lines[i].length + newlineLength}; } return {row: l-1, column: lines[l-1].length}; }; this.positionToIndex = function(pos, startRow) { var lines = this.$lines || this.getAllLines(); var newlineLength = this.getNewLineCharacter().length; var index = 0; var row = Math.min(pos.row, lines.length); for (var i = startRow || 0; i < row; ++i) index += lines[i].length + newlineLength; return index + pos.column; }; }).call(Document.prototype); exports.Document = Document; }); ace.define("ace/lib/lang",["require","exports","module"], function(require, exports, module) { "use strict"; exports.last = function(a) { return a[a.length - 1]; }; exports.stringReverse = function(string) { return string.split("").reverse().join(""); }; exports.stringRepeat = function (string, count) { var result = ''; while (count > 0) { if (count & 1) result += string; if (count >>= 1) string += string; } return result; }; var trimBeginRegexp = /^\s\s*/; var trimEndRegexp = /\s\s*$/; exports.stringTrimLeft = function (string) { return string.replace(trimBeginRegexp, ''); }; exports.stringTrimRight = function (string) { return string.replace(trimEndRegexp, ''); }; exports.copyObject = function(obj) { var copy = {}; for (var key in obj) { copy[key] = obj[key]; } return copy; }; exports.copyArray = function(array){ var copy = []; for (var i=0, l=array.length; i= '0' && ch <= '9') { string += ch; next(); } if (ch === '.') { string += '.'; while (next() && ch >= '0' && ch <= '9') { string += ch; } } if (ch === 'e' || ch === 'E') { string += ch; next(); if (ch === '-' || ch === '+') { string += ch; next(); } while (ch >= '0' && ch <= '9') { string += ch; next(); } } number = +string; if (isNaN(number)) { error("Bad number"); } else { return number; } }, string = function () { var hex, i, string = '', uffff; if (ch === '"') { while (next()) { if (ch === '"') { next(); return string; } else if (ch === '\\') { next(); if (ch === 'u') { uffff = 0; for (i = 0; i < 4; i += 1) { hex = parseInt(next(), 16); if (!isFinite(hex)) { break; } uffff = uffff * 16 + hex; } string += String.fromCharCode(uffff); } else if (typeof escapee[ch] === 'string') { string += escapee[ch]; } else { break; } } else { string += ch; } } } error("Bad string"); }, white = function () { while (ch && ch <= ' ') { next(); } }, word = function () { switch (ch) { case 't': next('t'); next('r'); next('u'); next('e'); return true; case 'f': next('f'); next('a'); next('l'); next('s'); next('e'); return false; case 'n': next('n'); next('u'); next('l'); next('l'); return null; } error("Unexpected '" + ch + "'"); }, value, // Place holder for the value function. array = function () { var array = []; if (ch === '[') { next('['); white(); if (ch === ']') { next(']'); return array; // empty array } while (ch) { array.push(value()); white(); if (ch === ']') { next(']'); return array; } next(','); white(); } } error("Bad array"); }, object = function () { var key, object = {}; if (ch === '{') { next('{'); white(); if (ch === '}') { next('}'); return object; // empty object } while (ch) { key = string(); white(); next(':'); if (Object.hasOwnProperty.call(object, key)) { error('Duplicate key "' + key + '"'); } object[key] = value(); white(); if (ch === '}') { next('}'); return object; } next(','); white(); } } error("Bad object"); }; value = function () { white(); switch (ch) { case '{': return object(); case '[': return array(); case '"': return string(); case '-': return number(); default: return ch >= '0' && ch <= '9' ? number() : word(); } }; return function (source, reviver) { var result; text = source; at = 0; ch = ' '; result = value(); white(); if (ch) { error("Syntax error"); } return typeof reviver === 'function' ? function walk(holder, key) { var k, v, value = holder[key]; if (value && typeof value === 'object') { for (k in value) { if (Object.hasOwnProperty.call(value, k)) { v = walk(value, k); if (v !== undefined) { value[k] = v; } else { delete value[k]; } } } } return reviver.call(holder, key, value); }({'': result}, '') : result; }; }); ace.define("ace/mode/json_worker",["require","exports","module","ace/lib/oop","ace/worker/mirror","ace/mode/json/json_parse"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var Mirror = require("../worker/mirror").Mirror; var parse = require("./json/json_parse"); var JsonWorker = exports.JsonWorker = function(sender) { Mirror.call(this, sender); this.setTimeout(200); }; oop.inherits(JsonWorker, Mirror); (function() { this.onUpdate = function() { var value = this.doc.getValue(); try { if (value) parse(value); } catch (e) { var pos = this.doc.indexToPosition(e.at-1); this.sender.emit("error", { row: pos.row, column: pos.column, text: e.message, type: "error" }); return; } this.sender.emit("ok"); }; }).call(JsonWorker.prototype); }); ace.define("ace/lib/es5-shim",["require","exports","module"], function(require, exports, module) { function Empty() {} if (!Function.prototype.bind) { Function.prototype.bind = function bind(that) { // .length is 1 var target = this; if (typeof target != "function") { throw new TypeError("Function.prototype.bind called on incompatible " + target); } var args = slice.call(arguments, 1); // for normal call var bound = function () { if (this instanceof bound) { var result = target.apply( this, args.concat(slice.call(arguments)) ); if (Object(result) === result) { return result; } return this; } else { return target.apply( that, args.concat(slice.call(arguments)) ); } }; if(target.prototype) { Empty.prototype = target.prototype; bound.prototype = new Empty(); Empty.prototype = null; } return bound; }; } var call = Function.prototype.call; var prototypeOfArray = Array.prototype; var prototypeOfObject = Object.prototype; var slice = prototypeOfArray.slice; var _toString = call.bind(prototypeOfObject.toString); var owns = call.bind(prototypeOfObject.hasOwnProperty); var defineGetter; var defineSetter; var lookupGetter; var lookupSetter; var supportsAccessors; if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { defineGetter = call.bind(prototypeOfObject.__defineGetter__); defineSetter = call.bind(prototypeOfObject.__defineSetter__); lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); } if ([1,2].splice(0).length != 2) { if(function() { // test IE < 9 to splice bug - see issue #138 function makeArray(l) { var a = new Array(l+2); a[0] = a[1] = 0; return a; } var array = [], lengthBefore; array.splice.apply(array, makeArray(20)); array.splice.apply(array, makeArray(26)); lengthBefore = array.length; //46 array.splice(5, 0, "XXX"); // add one element lengthBefore + 1 == array.length if (lengthBefore + 1 == array.length) { return true;// has right splice implementation without bugs } }()) {//IE 6/7 var array_splice = Array.prototype.splice; Array.prototype.splice = function(start, deleteCount) { if (!arguments.length) { return []; } else { return array_splice.apply(this, [ start === void 0 ? 0 : start, deleteCount === void 0 ? (this.length - start) : deleteCount ].concat(slice.call(arguments, 2))) } }; } else {//IE8 Array.prototype.splice = function(pos, removeCount){ var length = this.length; if (pos > 0) { if (pos > length) pos = length; } else if (pos == void 0) { pos = 0; } else if (pos < 0) { pos = Math.max(length + pos, 0); } if (!(pos+removeCount < length)) removeCount = length - pos; var removed = this.slice(pos, pos+removeCount); var insert = slice.call(arguments, 2); var add = insert.length; if (pos === length) { if (add) { this.push.apply(this, insert); } } else { var remove = Math.min(removeCount, length - pos); var tailOldPos = pos + remove; var tailNewPos = tailOldPos + add - remove; var tailCount = length - tailOldPos; var lengthAfterRemove = length - remove; if (tailNewPos < tailOldPos) { // case A for (var i = 0; i < tailCount; ++i) { this[tailNewPos+i] = this[tailOldPos+i]; } } else if (tailNewPos > tailOldPos) { // case B for (i = tailCount; i--; ) { this[tailNewPos+i] = this[tailOldPos+i]; } } // else, add == remove (nothing to do) if (add && pos === lengthAfterRemove) { this.length = lengthAfterRemove; // truncate array this.push.apply(this, insert); } else { this.length = lengthAfterRemove + add; // reserves space for (i = 0; i < add; ++i) { this[pos+i] = insert[i]; } } } return removed; }; } } if (!Array.isArray) { Array.isArray = function isArray(obj) { return _toString(obj) == "[object Array]"; }; } var boxedString = Object("a"), splitString = boxedString[0] != "a" || !(0 in boxedString); if (!Array.prototype.forEach) { Array.prototype.forEach = function forEach(fun /*, thisp*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, thisp = arguments[1], i = -1, length = self.length >>> 0; if (_toString(fun) != "[object Function]") { throw new TypeError(); // TODO message } while (++i < length) { if (i in self) { fun.call(thisp, self[i], i, object); } } }; } if (!Array.prototype.map) { Array.prototype.map = function map(fun /*, thisp*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0, result = Array(length), thisp = arguments[1]; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self) result[i] = fun.call(thisp, self[i], i, object); } return result; }; } if (!Array.prototype.filter) { Array.prototype.filter = function filter(fun /*, thisp */) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0, result = [], value, thisp = arguments[1]; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self) { value = self[i]; if (fun.call(thisp, value, i, object)) { result.push(value); } } } return result; }; } if (!Array.prototype.every) { Array.prototype.every = function every(fun /*, thisp */) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0, thisp = arguments[1]; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self && !fun.call(thisp, self[i], i, object)) { return false; } } return true; }; } if (!Array.prototype.some) { Array.prototype.some = function some(fun /*, thisp */) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0, thisp = arguments[1]; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self && fun.call(thisp, self[i], i, object)) { return true; } } return false; }; } if (!Array.prototype.reduce) { Array.prototype.reduce = function reduce(fun /*, initial*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } if (!length && arguments.length == 1) { throw new TypeError("reduce of empty array with no initial value"); } var i = 0; var result; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i++]; break; } if (++i >= length) { throw new TypeError("reduce of empty array with no initial value"); } } while (true); } for (; i < length; i++) { if (i in self) { result = fun.call(void 0, result, self[i], i, object); } } return result; }; } if (!Array.prototype.reduceRight) { Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, length = self.length >>> 0; if (_toString(fun) != "[object Function]") { throw new TypeError(fun + " is not a function"); } if (!length && arguments.length == 1) { throw new TypeError("reduceRight of empty array with no initial value"); } var result, i = length - 1; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i--]; break; } if (--i < 0) { throw new TypeError("reduceRight of empty array with no initial value"); } } while (true); } do { if (i in this) { result = fun.call(void 0, result, self[i], i, object); } } while (i--); return result; }; } if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { var self = splitString && _toString(this) == "[object String]" ? this.split("") : toObject(this), length = self.length >>> 0; if (!length) { return -1; } var i = 0; if (arguments.length > 1) { i = toInteger(arguments[1]); } i = i >= 0 ? i : Math.max(0, length + i); for (; i < length; i++) { if (i in self && self[i] === sought) { return i; } } return -1; }; } if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { var self = splitString && _toString(this) == "[object String]" ? this.split("") : toObject(this), length = self.length >>> 0; if (!length) { return -1; } var i = length - 1; if (arguments.length > 1) { i = Math.min(i, toInteger(arguments[1])); } i = i >= 0 ? i : length - Math.abs(i); for (; i >= 0; i--) { if (i in self && sought === self[i]) { return i; } } return -1; }; } if (!Object.getPrototypeOf) { Object.getPrototypeOf = function getPrototypeOf(object) { return object.__proto__ || ( object.constructor ? object.constructor.prototype : prototypeOfObject ); }; } 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 (!owns(object, property)) return; var descriptor, getter, setter; descriptor = { enumerable: true, configurable: true }; if (supportsAccessors) { var prototype = object.__proto__; object.__proto__ = prototypeOfObject; var getter = lookupGetter(object, property); var setter = lookupSetter(object, property); object.__proto__ = prototype; if (getter || setter) { if (getter) descriptor.get = getter; if (setter) descriptor.set = setter; return descriptor; } } descriptor.value = object[property]; return descriptor; }; } if (!Object.getOwnPropertyNames) { Object.getOwnPropertyNames = function getOwnPropertyNames(object) { return Object.keys(object); }; } if (!Object.create) { var createEmpty; if (Object.prototype.__proto__ === null) { createEmpty = function () { return { "__proto__": null }; }; } else { createEmpty = function () { var empty = {}; for (var i in empty) empty[i] = null; empty.constructor = empty.hasOwnProperty = empty.propertyIsEnumerable = empty.isPrototypeOf = empty.toLocaleString = empty.toString = empty.valueOf = empty.__proto__ = null; return empty; } } Object.create = function create(prototype, properties) { var object; if (prototype === null) { object = createEmpty(); } else { if (typeof prototype != "object") throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); var Type = function () {}; Type.prototype = prototype; object = new Type(); object.__proto__ = prototype; } if (properties !== void 0) Object.defineProperties(object, properties); return object; }; } function doesDefinePropertyWork(object) { try { Object.defineProperty(object, "sentinel", {}); return "sentinel" in object; } catch (exception) { } } if (Object.defineProperty) { var definePropertyWorksOnObject = doesDefinePropertyWork({}); var definePropertyWorksOnDom = typeof document == "undefined" || doesDefinePropertyWork(document.createElement("div")); if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { var definePropertyFallback = Object.defineProperty; } } if (!Object.defineProperty || definePropertyFallback) { var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + "on this javascript engine"; Object.defineProperty = function defineProperty(object, property, descriptor) { if ((typeof object != "object" && typeof object != "function") || object === null) throw new TypeError(ERR_NON_OBJECT_TARGET + object); if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); if (definePropertyFallback) { try { return definePropertyFallback.call(Object, object, property, descriptor); } catch (exception) { } } if (owns(descriptor, "value")) { if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) { var prototype = object.__proto__; object.__proto__ = prototypeOfObject; delete object[property]; object[property] = descriptor.value; object.__proto__ = prototype; } else { object[property] = descriptor.value; } } else { if (!supportsAccessors) throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); if (owns(descriptor, "get")) defineGetter(object, property, descriptor.get); if (owns(descriptor, "set")) defineSetter(object, property, descriptor.set); } return object; }; } 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; }; } if (!Object.seal) { Object.seal = function seal(object) { return object; }; } if (!Object.freeze) { Object.freeze = function freeze(object) { return object; }; } 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); } if (!Object.preventExtensions) { Object.preventExtensions = function preventExtensions(object) { return object; }; } if (!Object.isSealed) { Object.isSealed = function isSealed(object) { return false; }; } if (!Object.isFrozen) { Object.isFrozen = function isFrozen(object) { return false; }; } if (!Object.isExtensible) { Object.isExtensible = function isExtensible(object) { if (Object(object) === object) { throw new TypeError(); // TODO message } var name = ''; while (owns(object, name)) { name += '?'; } object[name] = true; var returnValue = owns(object, name); delete object[name]; return returnValue; }; } 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; }; } if (!Date.now) { Date.now = function now() { return new Date().getTime(); }; } var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + "\u2029\uFEFF"; if (!String.prototype.trim || ws.trim()) { ws = "[" + ws + "]"; var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), trimEndRegexp = new RegExp(ws + ws + "*$"); String.prototype.trim = function trim() { return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); }; } function toInteger(n) { n = +n; if (n !== n) { // isNaN n = 0; } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } return n; } function isPrimitive(input) { var type = typeof input; return ( input === null || type === "undefined" || type === "boolean" || type === "number" || type === "string" ); } function toPrimitive(input) { var val, valueOf, toString; if (isPrimitive(input)) { return input; } valueOf = input.valueOf; if (typeof valueOf === "function") { val = valueOf.call(input); if (isPrimitive(val)) { return val; } } toString = input.toString; if (typeof toString === "function") { val = toString.call(input); if (isPrimitive(val)) { return val; } } throw new TypeError(); } var toObject = function (o) { if (o == null) { // this matches both null and undefined throw new TypeError("can't convert "+o+" to object"); } return Object(o); }; }); Swagger2-0.89/lib/Mojolicious/Command/000755 000765 000024 00000000000 13056113272 020722 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/lib/Mojolicious/Plugin/000755 000765 000024 00000000000 13056113272 020602 5ustar00jhthorsenstaff000000 000000 Swagger2-0.89/lib/Mojolicious/Plugin/Swagger2.pm000644 000765 000024 00000026652 13056113205 022630 0ustar00jhthorsenstaff000000 000000 package Mojolicious::Plugin::Swagger2; use Mojo::Base 'Mojolicious::Plugin'; use Mojo::JSON; use Mojo::Loader; use Mojo::Util qw(decamelize deprecated); use Swagger2; use JSON::Validator::OpenAPI::Mojolicious; use constant DEBUG => $ENV{SWAGGER2_DEBUG}; use constant IO_LOGGING => $ENV{SWAGGER2_IO_LOGGING}; # EXPERIMENTAL deprecated "Mojolicious::Plugin::Swagger2 is deprecated in favor of Mojolicious::Plugin::OpenAPI"; my $SKIP_OP_RE = qr(By|From|For|In|Of|To|With); my $LAYOUT = Mojo::Loader::data_section(__PACKAGE__, 'layouts/mojolicious_plugin_swagger.html.ep'); has url => ''; has _validator => sub { JSON::Validator::OpenAPI::Mojolicious->new; }; sub dispatch_to_swagger { return undef unless $_[1]->{op} and $_[1]->{id} and ref $_[1]->{params} eq 'HASH'; my ($c, $data) = @_; my $self = $c->stash('swagger.plugin'); my $reply = sub { $_[0]->send({json => {code => $_[2] || 200, id => $data->{id}, body => $_[1]}}) }; my $defaults = $self->{route_defaults}{$data->{op}} or return $c->$reply(_error('Unknown operationId.'), 400); my ($e, $input, @errors); return $c->$reply(_error($e), 501) if $e = _find_action($c, $defaults); for my $p (@{$defaults->{swagger_operation_spec}{parameters} || []}) { my $name = $p->{name}; my $value = $data->{params}{$name} // $p->{default}; my @e = $self->_validator->_validate_request_value($p, $name => $value); $input->{$name} = $value unless @e; push @errors, @e; } return $c->$reply({errors => \@errors}, 400) if @errors; return Mojo::IOLoop->delay( sub { my $delay = shift; my $action = $defaults->{action}; my $sc = $delay->data->{sc} = $defaults->{controller}->new(%$c); $sc->stash(swagger_operation_spec => $defaults->{swagger_operation_spec}); $sc->$action($input, $delay->begin); }, sub { my $delay = shift; my $data = shift; my $status = shift || 200; my @errors = $self->_validator->validate_response($c, $defaults->{swagger_operation_spec}, $status, $data); return $c->$reply($data, $status) unless @errors; warn "[Swagger2] Invalid response: @errors\n" if DEBUG; $c->$reply({errors => \@errors}, 500); }, ); } sub render_swagger { my ($c, $err, $data, $status) = @_; return $c->render(json => $err, status => $status) if %$err; return $c->render(ref $data ? (json => $data) : (text => $data), status => $status); } sub register { my ($self, $app, $config) = @_; my ($base_path, $paths, $r, $swagger); $swagger = $config->{swagger} || Swagger2->new->load($config->{url} || '"url" is missing'); $swagger = $swagger->expand; $paths = $swagger->api_spec->get('/paths') || {}; $app->plugin(PODRenderer => {no_perldoc => 1}) unless $app->renderer->helpers->{pod_to_html}; if ($config->{validate} // 1) { my @errors = $swagger->validate; die join "\n", "Swagger2: Invalid spec:", @errors if @errors; } if ($app->plugins->has_subscribers('swagger_route_added')) { warn "swagger_route_added hook will be deprecated. https://github.com/jhthorsen/swagger2/issues/65"; } else { $app->hook(swagger_route_added => \&_on_route_added); } local $config->{coerce} = $config->{coerce} || $ENV{SWAGGER_COERCE_VALUES}; $self->_validator->coerce($config->{coerce}) if $config->{coerce}; $self->_validator->schema($swagger->api_spec->data); $self->url($swagger->url); $app->helper(dispatch_to_swagger => \&dispatch_to_swagger) unless $app->renderer->get_helper('dispatch_to_swagger'); $app->helper(render_swagger => \&render_swagger) unless $app->renderer->get_helper('render_swagger'); $r = $config->{route}; if ($r and !$r->pattern->unparsed) { $r->to(swagger => $swagger); $r = $r->any($swagger->base_url->path->to_string); } if (!$r) { $r = $app->routes->any($swagger->base_url->path->to_string); $r->to(swagger => $swagger); } if (my $ws = $config->{ws}) { $ws->to('swagger.plugin' => $self); } $base_path = $swagger->api_spec->data->{basePath} = $r->to_string; $base_path =~ s!/$!!; for my $path (sort { length $a <=> length $b } keys %$paths) { my $around_action = $paths->{$path}{'x-mojo-around-action'} || $swagger->api_spec->get('/x-mojo-around-action'); my $controller = $paths->{$path}{'x-mojo-controller'} || $swagger->api_spec->get('/x-mojo-controller'); for my $http_method (grep { !/^x-/ } keys %{$paths->{$path}}) { my $op_spec = $paths->{$path}{$http_method}; my $route_path = $path; my %parameters = map { ($_->{name}, $_) } @{$op_spec->{parameters} || []}; $route_path =~ s/{([^}]+)}/{ my $name = $1; my $type = $parameters{$name}{'x-mojo-placeholder'} || ':'; "($type$name)"; }/ge; $op_spec->{'x-mojo-around-action'} = $around_action if !$op_spec->{'x-mojo-around-action'} and $around_action; $op_spec->{'x-mojo-controller'} = $controller if !$op_spec->{'x-mojo-controller'} and $controller; $app->plugins->emit(swagger_route_added => $r->$http_method($route_path => $self->_generate_request_handler($op_spec))); warn "[Swagger2] Add route $http_method $base_path$route_path\n" if DEBUG; } } if (my $spec_path = $config->{spec_path} // '/') { my $title = $swagger->api_spec->get('/info/title'); $title =~ s!\W!_!g; $r->get($spec_path)->to(cb => sub { _render_spec(shift, $swagger) })->name(lc $title); } if ($config->{ensure_swagger_response}) { $self->_ensure_swagger_response($app, $config->{ensure_swagger_response}, $swagger); } } sub _ensure_swagger_response { my ($self, $app, $responses, $swagger) = @_; my $base_path = $swagger->api_spec->data->{basePath}; $responses->{exception} ||= 'Internal server error.'; $responses->{not_found} ||= 'Not found.'; $base_path = qr{^$base_path}; $app->hook( before_render => sub { my ($c, $args) = @_; return unless my $template = $args->{template}; return unless my $msg = $responses->{$template}; return unless $c->req->url->path->to_string =~ $base_path; $args->{json} = _error($msg); } ); } sub _generate_request_handler { my ($self, $op_spec) = @_; my $defaults = {swagger_operation_spec => $op_spec}; my $handler = sub { my $c = shift; my ($e, @errors, %input); return $c->render_swagger(_error($e), {}, 501) if $e = _find_action($c, $defaults); $c = $defaults->{controller}->new(%$c); @errors = $self->_validator->validate_request($c, $op_spec, \%input); _io_error($c, Input => \@errors) if IO_LOGGING and @errors; return $c->render_swagger({errors => \@errors}, {}, 400) if @errors; return $c->delay( sub { my $action = $defaults->{action}; $c->app->log->debug( qq(Swagger2 routing to controller "$defaults->{controller}" and action "$action")); $c->$action(\%input, shift->begin); }, sub { my $delay = shift; my $data = shift; my $status = shift || 200; my @errors = $self->_validator->validate_response($c, $op_spec, $status, $data); return $c->render_swagger({}, $data, $status) unless @errors; _io_error($c, Output => \@errors) if IO_LOGGING and @errors; $c->render_swagger({errors => \@errors}, $data, 500); }, ); }; for my $p (@{$op_spec->{parameters} || []}) { $defaults->{$p->{name}} = $p->{default} if $p->{in} eq 'path' and defined $p->{default}; } if (my $around_action = $op_spec->{'x-mojo-around-action'}) { my $next = $handler; $handler = sub { my $c = shift; my $around = $c->can($around_action) || $around_action; $around->($next, $c, $op_spec); }; } $self->{route_defaults}{$op_spec->{operationId}} = $defaults; return $defaults, $handler; } sub _on_route_added { my ($self, $r) = @_; my $op_spec = $r->pattern->defaults->{swagger_operation_spec}; my $controller = $op_spec->{'x-mojo-controller'}; my $route_name; $route_name = $controller ? decamelize join '::', map { ucfirst $_ } $controller, $op_spec->{operationId} : decamelize $op_spec->{operationId}; $route_name =~ s/\W+/_/g; $r->name($route_name); } sub _render_spec { my ($c, $swagger) = @_; my $format = $c->stash('format') || 'json'; my $spec = $swagger->api_spec->data; my $url = $c->req->url->to_abs; local $spec->{id}; delete $spec->{id}; local $spec->{host} = $url->host_port; $swagger->base_url->host($url->host)->port($url->port); if ($format eq 'text') { $c->render(text => $swagger->pod->to_string); } elsif ($format eq 'html') { $c->render( handler => 'ep', inline => $LAYOUT, pod => $c->pod_to_html($swagger->pod->to_string) ); } else { $c->render(json => $spec); } } sub _error { return {errors => [{message => $_[0], path => '/'}]}; } sub _find_action { return if $_[1]->{controller}; # cached my ($c, $defaults) = @_; my $op = $defaults->{swagger_operation_spec}{operationId} or return 'operationId is missing.'; my $can = sub { $defaults->{controller}->can($defaults->{action}) ? '' : qq(Method "$defaults->{action}" not implemented.); }; # specify controller manually @$defaults{qw(action controller)} = _load($c, $op, $defaults->{swagger_operation_spec}{'x-mojo-controller'}); return $can->() if $defaults->{controller}; # "createFileInFileSystem" = ("createFile", "FileSystem") @$defaults{qw(action controller)} = _load($c, split $SKIP_OP_RE, $op); return $can->() if $defaults->{controller}; # "showPetById" = "showPet" $op =~ s!$SKIP_OP_RE.*$!!; # "show_fooPet" = ("show_foo", "Pet") @$defaults{qw(action controller)} = _load($c, $op =~ /^([a-z_]+)([A-Z]\w+)$/); return $can->() if $defaults->{controller}; return qq(Controller from operationId "$defaults->{swagger_operation_spec}{operationId}" could not be loaded.); } sub _io_error { my $c = shift; my $level = IO_LOGGING; $c->app->log->$level(sprintf '%s error: %s', shift, Mojo::JSON::encode_json(shift)); } sub _load { my ($c, $action, $controller) = @_; my (@classes, %uniq); return unless $controller; $action = decamelize ucfirst $action; if ($controller =~ /::/) { push @classes, $controller; } else { my $singular = $controller; $singular =~ s!s$!!; # "showPets" = "showPet" push @classes, grep { !$uniq{$_}++ } map { ("${_}::$controller", "${_}::$singular") } @{$c->app->routes->namespaces}; } while ($controller = shift @classes) { my $e = Mojo::Loader::load_class($controller); warn qq([Swagger2] Load "$controller": @{[ref $e ? $e : $e ? "Can't locate class" : "Success"]}.\n) if DEBUG; return ($action, $controller) if $controller->can('new'); } return; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::Swagger2 - Deprecated =head1 DEPRECATION WARNING See L. =head1 AUTHOR Jan Henning Thorsen - C =cut __DATA__ @@ layouts/mojolicious_plugin_swagger.html.ep <%= $swagger->api_spec->get('/info/title') %>
<%= $pod %>
Swagger2-0.89/lib/Mojolicious/Command/swagger2.pm000644 000765 000024 00000012035 13056113205 022776 0ustar00jhthorsenstaff000000 000000 package Mojolicious::Command::swagger2; use Mojo::Base 'Mojolicious::Command'; use Mojo::Util; use Swagger2; my $app = __PACKAGE__; # used in tests our $OUT = \*STDOUT; has description => 'Interface with Swagger2.'; has usage => <<"HERE"; Usage: # Make a request to a Swagger server @{[__PACKAGE__->_usage('client')]} # Edit an API file in your browser # This command also takes whatever option "morbo" takes @{[__PACKAGE__->_usage('edit')]} # Write POD to STDOUT @{[__PACKAGE__->_usage('pod')]} # Run perldoc on the generated POD @{[__PACKAGE__->_usage('perldoc')]} # Validate an API file @{[__PACKAGE__->_usage('validate')]} HERE sub run { my $self = shift; my $action = shift || 'unknown'; my $code = $self->can("_action_$action"); die $self->usage unless $code; $self->$code(@_); } sub _action_client { my ($self, $file, @args) = @_; unshift @args, $file if $ENV{SWAGGER_API_FILE}; $ENV{SWAGGER_COERCE_VALUES} //= 1; my $method = shift @args; my $args = {}; my $base_url = $ENV{SWAGGER_BASE_URL}; my $i = 0; return print $OUT $self->_usage_client unless $ENV{SWAGGER_API_FILE} ||= $file; return print $OUT $self->_documentation_for('') if !$method or $method =~ /\W/; require Swagger2::Client; my $client = Swagger2::Client->generate($ENV{SWAGGER_API_FILE}); for (@args) { return $self->_documentation_for($method) if $_ eq 'help'; $base_url = $args[$i + 1] if $_ eq '-b'; $args = Mojo::JSON::decode_json($args[0]) if /^\{/; $args->{$1} = $2 if /^(\w+)=(.*)/; $i++; } $client->base_url->parse($base_url) if $base_url; eval { my $res = $client->$method($args); print $OUT $res->json ? Mojo::Util::dumper($res->json) : $res->body; 1; } or do { my $e = $@; $e =~ s! at .* line.*!!s; warn "ERROR! $e\n"; }; } sub _action_edit { my ($self, $file, @args) = @_; unshift @args, $file if $ENV{SWAGGER_API_FILE}; $ENV{SWAGGER_API_FILE} ||= $file || ''; $ENV{SWAGGER_LOAD_EDITOR} = 1; $file ||= __FILE__; require Swagger2::Editor; system 'morbo', -w => $file, @args, $INC{'Swagger2/Editor.pm'}; } sub _action_perldoc { my ($self, $file) = @_; die $self->_usage('perldoc'), "\n" unless $file; require Mojo::Asset::File; my $asset = Mojo::Asset::File->new; $asset->add_chunk(Swagger2->new($file)->pod->to_string); system perldoc => $asset->path; } sub _action_pod { my ($self, $file) = @_; die $self->_usage('pod'), "\n" unless $file; print $OUT Swagger2->new($file)->pod->to_string; } sub _action_validate { my ($self, $file) = @_; my @errors; die $self->_usage('validate'), "\n" unless $file; @errors = Swagger2->new($file)->validate; unless (@errors) { print $OUT "$file is valid.\n"; return; } for my $e (@errors) { print $OUT "$e\n"; } } sub _documentation_for { my ($self, $needle) = @_; my $pod = Swagger2->new($ENV{SWAGGER_API_FILE})->pod; my $paths = $pod->{api_spec}->get('/paths') || {}; my @methods; for my $path (sort keys %$paths) { for my $method (sort keys %{$paths->{$path}}) { push @methods, $paths->{$path}{$method}{operationId} || join ' ', $method, $path; delete $paths->{$path}{$method} unless $methods[-1] eq $needle; } delete $paths->{$path} unless %{$paths->{$path}}; } unless ($needle) { print $OUT "$_\n" for sort @methods; return; } require Pod::Simple; my $pod_text = Pod::Text->new; $pod_text->output_fh($OUT); $pod_text->parse_string_document($pod->_paths_to_string); } sub _usage { my $self = shift; return "Usage: mojo swagger2 edit" if $_[0] eq 'edit'; return "Usage: mojo swagger2 perldoc path/to/spec.json" if $_[0] eq 'perldoc'; return "Usage: mojo swagger2 pod path/to/spec.json" if $_[0] eq 'pod'; return "Usage: mojo swagger2 validate path/to/spec.json" if $_[0] eq 'validate'; return "Usage: mojo swagger2 client path/to/spec.json [args]" if $_[0] eq 'client'; die "No usage for '@_'"; } sub _usage_client { my $self = shift; return < [args] # List methods mojo swagger2 client path/to/spec.json # Get documentation for a method mojo swagger2 client path/to/spec.json help # Specify spec and/or base URL from environment. # Useful for shell wrappers SWAGGER_API_FILE=path/to/spec.json mojo swagger2 client SWAGGER_BASE_URL=https://example.com/1.0 mojo swagger2 client # Example arguments mojo swagger2 client path/to/spec.json list_pets '{"limit":10}' mojo swagger2 client path/to/spec.json list_pets limit=10 owner=joe mojo swagger2 client path/to/spec.json -b https://example.com/1.0 list_pets limit=10 owner=joe HERE } 1; =encoding utf8 =head1 NAME Mojolicious::Command::swagger2 - Deprecated =head1 DEPRECATION WARNING See L. =head1 AUTHOR Jan Henning Thorsen - C =cut Swagger2-0.89/examples/websocket.pl000644 000765 000024 00000004540 12757311624 020456 0ustar00jhthorsenstaff000000 000000 #!/usr/bin/env perl use lib 'lib'; use Mojolicious::Lite; use t::Api; # How to run this exampl: # 1) Run ./examples/websocket.pl daemon --listen http://*:3000 # 2) Open up http://localhost:3000 in your browser. # 3) Open the developer console in your browser. # 4) Reload. # 5) See which requests are passed over the WebSocket or as plain HTTP. no warnings 'redefine'; sub t::Api::list_pets { my ($c, $args, $cb) = @_; state $i = 42; $c->$cb([{id => $i++, name => "Catwoman"}], 200); } get '/' => 'index'; get '/asset/swagger-client' => sub { my $c = shift; $c->reply->asset(Swagger2->new->javascript_client); }; my $ws = websocket '/ws' => sub { my $c = shift; $c->on( json => sub { my ($c, $data) = @_; return if $c->dispatch_to_swagger($data); } ); }; app->plugin(Swagger2 => {url => 't/data/petstore.json', ws => $ws}); app->start; __DATA__ @@ index.html.ep % if (param('ws') // 1) { %= link_to "Disable websockets", url_with()->query(ws => 0) % } else { %= link_to "Enable websockets", url_with()->query(ws => 1) % }

Loading Swagger spec...


<%= (param('ws') // 1) ? "WebSocket response" : "Plain HTTP response" %>:
Plain HTTP response: %= javascript '/asset/swagger-client.js'; %= javascript begin var client = new swaggerClient(); var clientLoaded = function(err) { document.getElementById("loaded").innerHTML = err || 'Specification loaded.'; if (err) return; // Request over WebSocket or plain HTTP this.listPets({limit: 10}, function(err, xhr) { document.getElementById("pets").innerHTML = JSON.stringify(err || xhr.body); }); // Request over plain HTTP this.http().listPets({limit: 10}, function(err, xhr) { document.getElementById("pets_http").innerHTML = JSON.stringify(err || xhr.body); }); }; if (location.href.indexOf('ws=0') == -1) { var ws = new WebSocket("<%= url_for('/ws')->to_abs->scheme('ws') %>"); ws.onopen = function() { client.ws(ws).load("/api", clientLoaded); }; } else { client.load("/api", clientLoaded); } % end